Python 用chain()组合多个迭代器,可以用chain()函数将多个迭代器组合为单个迭代器,比如将被groupby()函数分开的数据重新组合起来。对于简单集合,用这个方法可以一次处理多个集合。
如果需要在一个简单迭代序列中处理多个文件中的数据,可以使用chain()函数结合contextlib.ExitStack()方法来实现,具体做法如下:
from contextlib import ExitStack
import csv
def row_iter_csv_tab(*filenames: str) -> Iterator[List[str]]:
with ExitStack() as stack:
files = [
stack.enter_context(cast(TextIO, open(name, 'r')))
for name in filenames
] # type: List[TextIO]
readers = map(
lambda f: csv.reader(f, delimiter='\t'),
files)
yield from chain(*readers)
首先创建了一个包含多个打开的上下文的ExitStack对象。当with语句执行完毕后,ExitStack对象中所有打开的对象都会合理地关闭,所以在ExitStack对象中创建了多个打开的文件对象。
基于files变量中的多个文件对象,我们创建了一系列CSV readers对象,保存在readers变量中。所有文件都是以Tab分隔的,因此便于用一个简单的函数处理所有文件。
也可以用如下方式打开一系列文件:
readers = [csv.reader(f, delimiter='\t') for f in files]
最后,通过chain(*readers)将多读取器合并成单个迭代器,包含所有文件的行序列数据。
注意,这里不能用
return返回chain(*readers),如果使用return,函数将退出with语句,关闭所有文件,所以这里必须用yield返回某个文件的所有行,同时不退出with语句。
极客教程