我想处理一个文本文件(逐行)。数量(最初未知)的连续线属于同一实体(即,它们与该线携带相同的标识符)。例如:
line1: stuff, stuff2, stuff3, ID1, stuff4, stuff5
line2: stuff, stuff2, stuff3, ID1, stuff4, stuff5
line3: stuff, stuff2, stuff3, ID1, stuff4, stuff5
line4: stuff, stuff2, stuff3, ID2, stuff4, stuff5
line5: stuff, stuff2, stuff3, ID2, stuff4, stuff5
...
在该虚拟线中,线1-3属于实体ID1,线4-5至ID2。我想将每行作为字典阅读,然后将它们嵌套到包含IDX的所有字典的字典中(例如,字典ID1分别具有3个嵌套的第1-3行字典)。
更具体地说,我想定义一个函数:
我希望稍后能够再次调用该函数,以在下一个词典中读取以下标识符(ID2)和更高版本的ID3等的所有行。我遇到的问题之一是,我需要在每个无论我当前的行仍在携带感兴趣的ID还是已经有一个新的ID。如果是新字典,我肯定可以停止并返回字典,但是在下一轮(例如ID2)中,ID2的第一行已经被读取,因此我似乎丢失了该行。
换句话说:一旦遇到具有新ID的行,我想以某种方式重置该计数器,以便在下一次迭代中,不会丢失具有新ID的第一行。
这似乎是一项简单的任务,但我无法找到一种优雅地完成此任务的方法。我目前在函数之间传递一些“内存”标志/变量,以跟踪新ID的第一行在上一次迭代中是否已被读取。那是相当大的并且容易出错。
感谢您的阅读...任何想法/提示都将受到高度赞赏。如果有些要点不清楚,请询问。
这是我的“解决方案”。从正确打印字典的意义上讲,它似乎可以正常工作(尽管我敢肯定有一种更优雅的方法可以做到这一点)。我也忘记提及文本文件很大,因此我想逐个ID地处理它,而不是将整个文件读入内存。
with open(infile, "r") as f:
newIDLine = None
for line in f:
if not line:
break
# the following function returns the ID
ID = get_ID_from_line(line)
counter = 1
ID_Dic = dict()
# if first line is completely new (i.e. first line in infile)
if newIDLine is None:
currID = ID
# the following function returns the line as a dic
ID_Dic[counter] = process_line(line)
# if first line of new ID was already read in
# the previous "while" iteration (see below).
if newIDLine is not None:
# if the current "line" is of the same ID then the
# previous one: put previous and current line in
# the same dic and start the while loop.
if ID == oldID:
ID_Dic[counter] = process_line(newIDLine)
counter += 1
ID_Dic[counter] = process_line(line)
currID = ID
# iterate over the following lines until file end or
# new ID starts. In the latter case: keep the info in
# objects newIDline and oldID
while True:
newLine = next(f)
if not newLine:
break
ID = get_ID_from_line(newLine)
if ID == currID:
counter += 1
ID_Dic[counter] = process_line(newLine)
# new ID; save line for the upcomming ID dic
if not ID == currID:
newIDLine = newLine
oldID = ID
break
# at this point it would be great to return the Dictionary of
# the current ID to the calling function but at return to this
# function continue where I left off.
print ID_Dic
如果希望此函数为每个id延迟返回一个字典,则应使用yield而不是return使其成为生成器函数。在每个ID的末尾,产生该ID的字典。然后,您可以遍历该生成器。
要处理该文件,请编写一个生成器函数,该函数将在源上进行迭代,除非您向其发送了一个值,在这种情况下,该函数接下来将返回该值,然后返回迭代。(例如,这是我为自己完成此操作的一个模块:politer.py。)
然后,如果您不想要它,可以通过发送值“ back”轻松解决此问题:
with open(infile, 'r') as f:
polite_f = politer(f)
current_id = None
while True:
id_dict = {}
for i, line in enumerate(polite_f):
id = get_id_from_line(line)
if id != current_id:
polite_f.send(line)
break
else:
id_dict[i] = process_line(line)
if current_id is not None:
yield id_dict
current_id = id
请注意,这会使状态处理在其所属的生成器中保持抽象状态。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句