我的Python代码支持以其他名为BLT format的人创建的文件格式读写数据。 BLT格式是空格和换行符独立,因为换行符就像其他空格一样。这种格式的主要条目是“选票”,以“0”结尾,例如,
1 2 3 0
由于格式与换行符无关,因此也可以写为
1 2
3 0
或者你可以在一条线上进行多次投票:
1 2 3 0 4 5 6 0
这些文件可能非常大,所以我不想将整个文件读入内存。基于行的读取很复杂,因为数据不是基于行的。以节省内存的方式处理这些文件的好方法是什么?
答案 0 :(得分:3)
对我来说,解决这个问题最直接的方法是使用发电机。
def tokens(filename):
with open(filename) as infile:
for line in infile:
for item in line.split():
yield int(item)
def ballots(tokens):
ballot = []
for t in tokens:
if t:
ballot.append(t)
else:
yield ballot
ballot = []
t = tokens("datafile.txt")
for b in ballots(t):
print b
我看到@katrielalex发布了一个使用生成器的解决方案,而我发布了我的解决方案。我们之间的区别在于我使用了两个独立的生成器,一个用于文件中的单个标记,另一个用于您要解析的特定数据结构。前者作为参数传递给后者,基本思想是您可以为要解析的每个数据结构编写类似ballots()
的函数。您可以迭代生成器生成的所有内容,或者在任一生成器上调用next()
以获取下一个标记或选票(在用完时准备好StopIteration
异常,或者将生成器写入在用完实际数据时生成None
之类的标记值,并检查该值。
将整个事物包装在一个类中是非常简单的。事实上......
class Parser(object):
def __init__(self, filename):
def tokens(filename):
with open(filename) as infile:
for line in infile:
for item in line.split():
yield int(item)
self.tokens = tokens(filename)
def ballots(self):
ballot = []
for t in self.tokens:
if t:
ballot.append(t)
else:
yield ballot
ballot = []
p = Parser("datafile.txt")
for b in p.ballots():
print b
答案 1 :(得分:1)
使用generator:
>>> def ballots(f):
... ballots = []
... for line in f:
... for token in line.split():
... if token == '0':
... yield ballots
... ballots = []
... else:
... ballots.append(token)
这将逐行读取文件,在所有空格上拆分,然后将行中的标记逐个附加到列表中。每当达到零时,该选票为yield
并且列表重置为空。