在Python中,如何迭代一个迭代器,然后迭代另一个迭代器?

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

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]: 

但是这将两个文件读入内存,我宁愿避免。

使用itertools.chain

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

fileinput模块还提供了一个类似的function:

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

你也可以用简单的生成器expression式来完成它:

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

用这个方法你可以在expression式中指定一些条件

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

上面的例子相当于这个带有循环的生成器

 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' 

我认为对这个特定的文件问题最Pythonic的方法是使用fileinput模块(因为你需要复杂的上下文pipe理器或openerror handling),我将开始与Ashwini的例子,但添加了一些东西。 首先,最好用U标志打开Universal Newlines的支持(假设你的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