python 读取整个文件的行,并有效地将我想要的行存储在列表中
python read lines of an entire file, and efficiently storing the ones I want in lists
我有一个重复以下块结构的文本文件:
EL_TEXT
LAYER 6
DATATYPE 0
XY 2677000: 2316500
2677000: 2340500
2707000: 2340500
2707000: 2316500
2677000: 2316500
ENDEL
...
并且这些块在文本文件中以不同的值重复自身。它们总是以 ENDEL
结尾
我想阅读并找到所有行,例如 "LAYER 6"(或 "LAYER 6 \n")并将这些行存储到列表中。还将这些块的 XY 坐标包含到 XY 元组列表中 [(2677000, 2316500), ...]
这样最终的列表就像
onelayer6polygon = [(2677000, 2316500), (2677000, 2340500), ...]
listofpolygonsL6 = [[(2677000, 2316500), (2677000, 2340500), ...], [...], ...]
我怎样才能在 python 中有效地做到这一点?即只读取文件的某些行,并且只读取一次,推进位置 lseek
以跳过不是我想要的图层的坐标。
据我所知,for line in file:
将读取所有行,直到 EOF
,但我只需要读取和存储(以及稍后处理)具有我指定的层号的行。用 while 循环来处理索引也不利于检测 EOF
,对吗?
As far as I understood for line in file:
will read all the lines until the EOF
, but I only need to read and store (and later process) the ones with the layer number I specify.
是也不是。遍历文件将逐行读取整个文件,直到到达文件末尾。但是它会一行接一行地读取,而不会存储内容。因此,您可以自行决定跳过您不感兴趣的行,并在遇到它们时存储您想要保留的信息。
请注意,您必须完整阅读文件才能遍历行。没有行间跳转的概念,你只能在字节(或字符)级别上寻找,所以为了知道哪一行你需要检查所有字符寻找换行符。因此,除非您知道每个块总共总是 X 个字符,否则您将不得不阅读您不感兴趣的块,以便找到下一个块的开始。
也就是说,您通常使用状态机来解决此类任务:您逐行读取文件,当您读取一行时,您可以选择更改机器状态以将其设置为一种不同的“模式”。
在您的情况下,模式可能在“第 6 层块内”,因此您应该从以下开始:
inLayer6Block = False
for line in file:
# strip trailing whitespace, since every line ends with the line break
line = line.rstrip()
# if we see the `LAYER 6` line, we start our block
if line == 'LAYER 6':
inLayer6Block = True
# if we see the `ENDEL` line, we are no longer in the block
elif line == 'ENDEL':
inLayer6Block = False
所以现在剩下的就是添加逻辑来处理介于两者之间的情况,当 inLayer6Block
为真时。我现在将此留给您来扩展上面的代码。通常,您希望有一个列表来存储块中的内容,只要您处于 inLayer6Block
状态,就可以附加到该块中。为了单独存储每个块,您将有另一个块,您将该单块列表附加到块结束时。
我有一个重复以下块结构的文本文件:
EL_TEXT
LAYER 6
DATATYPE 0
XY 2677000: 2316500
2677000: 2340500
2707000: 2340500
2707000: 2316500
2677000: 2316500
ENDEL
...
并且这些块在文本文件中以不同的值重复自身。它们总是以 ENDEL
结尾
我想阅读并找到所有行,例如 "LAYER 6"(或 "LAYER 6 \n")并将这些行存储到列表中。还将这些块的 XY 坐标包含到 XY 元组列表中 [(2677000, 2316500), ...]
这样最终的列表就像
onelayer6polygon = [(2677000, 2316500), (2677000, 2340500), ...]
listofpolygonsL6 = [[(2677000, 2316500), (2677000, 2340500), ...], [...], ...]
我怎样才能在 python 中有效地做到这一点?即只读取文件的某些行,并且只读取一次,推进位置 lseek
以跳过不是我想要的图层的坐标。
据我所知,for line in file:
将读取所有行,直到 EOF
,但我只需要读取和存储(以及稍后处理)具有我指定的层号的行。用 while 循环来处理索引也不利于检测 EOF
,对吗?
As far as I understood
for line in file:
will read all the lines until theEOF
, but I only need to read and store (and later process) the ones with the layer number I specify.
是也不是。遍历文件将逐行读取整个文件,直到到达文件末尾。但是它会一行接一行地读取,而不会存储内容。因此,您可以自行决定跳过您不感兴趣的行,并在遇到它们时存储您想要保留的信息。
请注意,您必须完整阅读文件才能遍历行。没有行间跳转的概念,你只能在字节(或字符)级别上寻找,所以为了知道哪一行你需要检查所有字符寻找换行符。因此,除非您知道每个块总共总是 X 个字符,否则您将不得不阅读您不感兴趣的块,以便找到下一个块的开始。
也就是说,您通常使用状态机来解决此类任务:您逐行读取文件,当您读取一行时,您可以选择更改机器状态以将其设置为一种不同的“模式”。
在您的情况下,模式可能在“第 6 层块内”,因此您应该从以下开始:
inLayer6Block = False
for line in file:
# strip trailing whitespace, since every line ends with the line break
line = line.rstrip()
# if we see the `LAYER 6` line, we start our block
if line == 'LAYER 6':
inLayer6Block = True
# if we see the `ENDEL` line, we are no longer in the block
elif line == 'ENDEL':
inLayer6Block = False
所以现在剩下的就是添加逻辑来处理介于两者之间的情况,当 inLayer6Block
为真时。我现在将此留给您来扩展上面的代码。通常,您希望有一个列表来存储块中的内容,只要您处于 inLayer6Block
状态,就可以附加到该块中。为了单独存储每个块,您将有另一个块,您将该单块列表附加到块结束时。