Python迭代地处理多个文件,没有明确的for循环

时间:2017-06-20 13:20:46

标签: python unix command-line io

我有一个脚本,它使用大量文本来训练模型。它现在写的方式我可以从文件或stdin读取

parser.add_argument('-i', help='input_file', default=sys.stdin)
... # do a bunch of other stuff
if args.i is sys.stdin:
    m.train(args.i)
else:
    m.train(open(args.i, 'r'))

然后我可以将我的脚本称为:

python myscript.py -i trainingdata.txt

cat trainingdata.txt | python myscript.py

如果我想搜索文件系统,并使用多个文件来训练模型,第二个版本特别有用。然而,由于管道,如果我同时尝试使用cProfiler(即

)进行分析,这会变得棘手
python -m cProfile myscript.py ... 

我知道我可以使用-i选项向其发送多个文件,并迭代文件,但之后我将不得不更改train()方法的行为以避免覆盖数据。

是否有一种很好的方法可以打开一个IO通道,因为没有更好的表达式,可以连接输入而无需逐行读取和写入?

1 个答案:

答案 0 :(得分:2)

您可以chain打开文件并使用生成器从yield打开文件名中的文件:

from itertools import chain

def yield_open(filenames):
    for filename in filenames:
        with open(filename, 'r') as file:
            yield file

def train(file):
    for line in file:
        print(line, end='')
    print()

files = chain.from_iterable(yield_open(filenames=['file1.txt', 'file2.txt']))
train(files)

这样做的好处是,当时只有一个文件是打开的。

您也可以将其用作“数据管道”(可能更具可读性):

file_gen = yield_open(filenames=['file1.txt', 'file2.txt'])
files = chain.from_iterable(file_gen)
train(files)