在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理器或open
error 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