【问题标题】:In Python, how do I iterate over one iterator and then another?在 Python 中,我如何迭代一个迭代器,然后再迭代另一个?
【发布时间】:2023-03-17 17:35:01
【问题描述】:

我想迭代两个不同的迭代器,像这样:

file1 = open('file1', 'r')
file2 = open('file2', 'r')
for item in one_then_another(file1, file2):
    print item

我希望先打印 file1 的所有行,然后打印 file2 的所有行。

我想要一些通用的东西,因为迭代器可能不是文件,这只是一个例子。我知道我可以这样做:

for item in [file1]+[file2]:

但这会将两个文件都读入内存,我希望避免这样做。

【问题讨论】:

  • 对于未来的读者来说,正如 Ashwini 所说的,此问题中要求的最佳通用答案是 itertools.chain。
  • 如果您正在处理文件,fileinput 是唯一真正的解决方案。

标签: python file iteration


【解决方案1】:

使用itertools.chain:

from itertools import chain
for line in chain(file1, file2):
   pass

fileinput 模块也提供了类似的功能:

import fileinput
for line in fileinput.input(['file1', 'file2']):
   pass

【讨论】:

    【解决方案2】:

    你也可以用简单的generator expression

    for line in (l for f in (file1, file2) for l in f):
        # do something with line
    

    使用此方法,您可以在表达式本身中指定一些条件

    for line in (l for f in (file1, file2) for l in f if 'text' in l):
        # do something with line which contains 'text'
    

    上面的例子等价于这个带有循环的generator

    def genlinewithtext(*files):
        for file in files:
            for line in file:
                if 'text' in line:
                    yield line
    
    for line in genlinewithtext(file1, file2):
        # do something with line which contains 'text'
    

    【讨论】:

      【解决方案3】:

      我认为解决这个特定文件问题的最 Pythonic 的方法是使用 fileinput 模块(因为您需要复杂的上下文管理器或使用 open 进行错误处理),我将从 Ashwini 的示例开始,但是添加一些东西。首先,最好使用U 标志打开以支持通用换行符(假设您的Python 是用它编译的,而且大多数都是),(r 是默认模式,但显式优于隐式)。如果您与其他人一起工作,最好支持他们为您提供任何格式的文件。

      import fileinput
      
      for line in fileinput.input(['file1', 'file2'], mode='rU'):
         pass
      

      这也可以在命令行上使用,因为如果你这样做,它将需要 sys.argv[1:]:

      import fileinput
      
      for line in fileinput.input(mode='rU'):
         pass
      

      你会像这样在你的 shell 中传递文件:

      $ python myscript.py file1 file2
      

      【讨论】:

      • 您能否将模式值更正为“rU”。当我尝试使用 'Ur' 的代码时,解释器会这样抱怨:“ValueError: FileInput opening mode must be one of 'r', 'rU', 'U' and 'rb'”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 2017-03-18
      • 1970-01-01
      • 2013-06-17
      • 2018-09-23
      相关资源
      最近更新 更多