从嵌套字典中的文件中读取最初数量未知的N行,然后在下一次迭代的N + 1行开始

罗舒

我想处理一个文本文件(逐行)。数量(最初未知)的连续线属于同一实体(即,它们与该线携带相同的标识符)。例如:

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行字典)。

更具体地说,我想定义一个函数:

  1. 打开文件
  2. 将实体ID1的所有(但仅)行读入单个词典
  3. 返回包含ID1行的嵌套字典的字典

我希望稍后能够再次调用该函数,以在下一个词典中读取以下标识符(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
llb

如果希望此函数为每个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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Bash 从 Z 行开始从文件中读取 N 行

来自分类Dev

从Ubuntu中的命名管道一次读取n行

来自分类Dev

RxJS :(时间)在下一次发射后开始的缓冲区

来自分类Dev

错误4预期的开始标签,找不到“ <”(在n / a-第1行,第1列中)

来自分类Dev

从指定行开始开始迭代csv文件?

来自分类Dev

ifstream在下一次迭代中不会打开文件

来自分类Dev

从特定行开始读取文件

来自分类Dev

为什么在外循环中 isstringstream 迭代器只迭代一次,而从文件中读取,尽管该文件中存在其他行?

来自分类Dev

从某一行开始,每第 n 行替换一次

来自分类Dev

从匹配的字符串中删除第n行(在文件中仅出现一次)

来自分类Dev

从多个文件一次读取1行

来自分类Dev

将2行合并为1行(开始和结束时间)

来自分类Dev

获取停止(行x)和开始(行x + 1)之间的时间间隔

来自分类Dev

如何为每个Java运行从CSV文件解析一行,为下一次运行解析下一行?

来自分类Dev

如何为每个Java运行从CSV文件解析一行,为下一次运行解析下一行呢?

来自分类Dev

从file2中给定的特定单词开始提取file1中的行

来自分类Dev

从行开始的Unix cat

来自分类Dev

从底部开始删除行

来自分类Dev

在python中从特定行开始读取

来自分类Dev

读取文件中的行,然后添加直到行数达到一定数量为止

来自分类Dev

R:循环遍历行直到满足条件,然后在下一行重新开始

来自分类Dev

在下n行中迭代Pandas数据框

来自分类Dev

带有尾源的SpringXD流一次又一次地读取文件中的所有行,而不仅仅是最后n行

来自分类Dev

删除一行后,我希望主键再次从 1 开始。所以有可能吗

来自分类Dev

如何从sed文件的第n行开始?

来自分类Dev

如何从sed文件的第n行开始?

来自分类Dev

从文件一次复制x行,然后将其粘贴到Python的(^ v)中

来自分类Dev

匹配直到下一行开始

来自分类Dev

使用bash脚本一次读取n行

Related 相关文章

  1. 1

    Bash 从 Z 行开始从文件中读取 N 行

  2. 2

    从Ubuntu中的命名管道一次读取n行

  3. 3

    RxJS :(时间)在下一次发射后开始的缓冲区

  4. 4

    错误4预期的开始标签,找不到“ <”(在n / a-第1行,第1列中)

  5. 5

    从指定行开始开始迭代csv文件?

  6. 6

    ifstream在下一次迭代中不会打开文件

  7. 7

    从特定行开始读取文件

  8. 8

    为什么在外循环中 isstringstream 迭代器只迭代一次,而从文件中读取,尽管该文件中存在其他行?

  9. 9

    从某一行开始,每第 n 行替换一次

  10. 10

    从匹配的字符串中删除第n行(在文件中仅出现一次)

  11. 11

    从多个文件一次读取1行

  12. 12

    将2行合并为1行(开始和结束时间)

  13. 13

    获取停止(行x)和开始(行x + 1)之间的时间间隔

  14. 14

    如何为每个Java运行从CSV文件解析一行,为下一次运行解析下一行?

  15. 15

    如何为每个Java运行从CSV文件解析一行,为下一次运行解析下一行呢?

  16. 16

    从file2中给定的特定单词开始提取file1中的行

  17. 17

    从行开始的Unix cat

  18. 18

    从底部开始删除行

  19. 19

    在python中从特定行开始读取

  20. 20

    读取文件中的行,然后添加直到行数达到一定数量为止

  21. 21

    R:循环遍历行直到满足条件,然后在下一行重新开始

  22. 22

    在下n行中迭代Pandas数据框

  23. 23

    带有尾源的SpringXD流一次又一次地读取文件中的所有行,而不仅仅是最后n行

  24. 24

    删除一行后,我希望主键再次从 1 开始。所以有可能吗

  25. 25

    如何从sed文件的第n行开始?

  26. 26

    如何从sed文件的第n行开始?

  27. 27

    从文件一次复制x行,然后将其粘贴到Python的(^ v)中

  28. 28

    匹配直到下一行开始

  29. 29

    使用bash脚本一次读取n行

热门标签

归档