【问题标题】:Multiline file read in Python用 Python 读取多行文件
【发布时间】:2012-09-29 06:00:21
【问题描述】:

我正在寻找一种可以从文件中读取多行(一次 10 行)的 Python 方法。我已经查看了readlines(sizehint),我尝试传递值 10 但不只读取 10 行。它实际上一直读取到文件末尾(我已经尝试过小文件)。每行有 11 个字节长,每次读取都应该获取 10 行。如果找到少于 10 行,则仅返回这些行。我的实际文件包含超过 150K 行。

知道如何实现这一点吗?

【问题讨论】:

  • 方法可以自己写
  • readlines 读取整个文件。可选参数不限制行数。

标签: python file file-read


【解决方案1】:

应该这样做

def read10Lines(fp):
    answer = []
    for i in range(10):
        answer.append(fp.readline())
    return answer

或者,列表推导:

ten_lines = [fp.readline() for _ in range(10)]

在这两种情况下,fp = open('path/to/file')

【讨论】:

    【解决方案2】:

    你正在寻找itertools.islice():

    with open('data.txt') as f:
        lines = []
        while True:
            line = list(islice(f, 10)) #islice returns an iterator ,so you convert it to list here.
            if line:                     
                #do something with current set of <=10 lines here
                lines.append(line)       # may be store it 
            else:
                break
        print lines    
    

    【讨论】:

    • 使用islice 的问题是isliceobject 是只读的。因此,如果 OP 想要根据当前行的条件检查之前的行,他将不得不手动缓存它。使用列表可能会更好(取决于用例)
    • @inspectorG4dget:但您的回答也存在同样的问题。您正在阅读 10 行并返回它们。仍然由调用者来缓存前一批行。
    • @jdi:不是我的意思。如果我阅读第 1-5 行和第 6 行,想查看第 3 行,我无法在没有另一个缓存的情况下使用islice。我指的是同一批次中的行,而不是之前批次中的行
    • 他正在代码中将其转换为列表。它所需要的只是将它分配给一个变量。我认为打印只是为了简单起见......lines = list(lines)
    • 我只看到一个编辑。它最初被转换为列表,只是打印..没有保存。无论如何。 +1 好答案。
    【解决方案3】:
    from itertools import groupby, count
    with open("data.txt") as f:
        groups = groupby(f, key=lambda x,c=count():next(c)//10)
        for k, v in groups:
            bunch_of_lines = list(v)
            print bunch_of_lines
    

    【讨论】:

      【解决方案4】:

      另一个可以摆脱愚蠢的无限循环以支持更熟悉的for 循环的解决方案依赖于itertools.izip_longest 和迭代器的一个小技巧。诀窍是zip(*[iter(iterator)]*n)iterator 分解成大小为 n 的块。由于文件已经是类似生成器的迭代器(而不是类似序列),我们可以这样写:

      from itertools import izip_longest
      with open('data.txt') as f:
          for ten_lines in izip_longest(*[f]*10,fillvalue=None):
              if ten_lines[-1] is None:
                 ten_lines = filter(ten_lines) #filter removes the `None` values at the end
              process(ten_lines) 
      

      【讨论】:

        猜你喜欢
        • 2016-04-28
        • 2018-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-24
        相关资源
        最近更新 更多