我有一个文本文件,它重复如下的块结构:
EL_TEXT
第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
,对吧?
答案 0 :(得分:1)
据我所知
for line in file:
将读取EOF
之前的所有行,但我只需要读取并存储(以后处理)具有我指定的图层编号的行。
是和否。循环遍历文件将逐行读取整个文件,直到到达文件末尾。但它会逐行读取一行,而不会存储内容。因此,您可以跳过您不感兴趣的行,并在遇到它们时存储您想要保留的信息。
请注意,您必须完全读取文件才能遍历行。没有在行之间跳转的概念,你只能在字节(或字符)级别上搜索,所以为了知道什么是行,你需要检查寻找换行符的所有字符。因此,除非您知道每个块总是总共为X个字符,否则您必须读取您不感兴趣的块才能找到下一个块的开头。
话虽这么说,您通常使用状态机解决此类任务:您逐行读取文件,当您读取一行时,您可以选择更改计算机的状态以将其设置为不同的“模式”。
在你的情况下,模式可能是“在LAYER 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
状态,就会附加到该列表中。为了分别存储每个块,你可以在块结束时将另一个块附加到单块列表中。