什么是交织文本文件内容的最具python风格的方式?
问题: 如果我有一个文件列表,那么如何打印每个文件的第1行 第2行,等等。?(显然,我是Python新手……) 例如:什么是交织文本文件内容的最具python风格的方式?,python,Python,问题: 如果我有一个文件列表,那么如何打印每个文件的第1行 第2行,等等。?(显然,我是Python新手……) 例如: file1: foo1 bar1 file2: foo2 bar2 file3: foo3 bar3 函数调用: names = ["file1", "file2", "file3"] myfct(names) 期望输出: foo1 foo2 foo3 bar1 bar2 bar3 我就是这样做的,但我相信还有一种更优雅、更像蟒蛇的方式: def myfct(fil
file1:
foo1
bar1
file2:
foo2
bar2
file3:
foo3
bar3
函数调用:
names = ["file1", "file2", "file3"]
myfct(names)
期望输出:
foo1
foo2
foo3
bar1
bar2
bar3
我就是这样做的,但我相信还有一种更优雅、更像蟒蛇的方式:
def myfct(files):
file_handlers = []
for myfile in files:
file_handlers.append(open(myfile))
while True:
done = False
for handler in file_handlers:
line = handler.readline()
eof = len(line) == 0 # wrong
if (eof):
done = True
break
print(line, end = "")
print()
if done == True:
break
注意:我正在使用Python2.6,其中包含来自未来导入打印功能的
,,如果所有文件都有相同的行数,或者如果您想在任何文件用完后立即停止,Ignacio的答案是完美的。但是,如果希望支持不同长度的文件,则应使用itertools
文档中的“循环”方法:
for lines in itertools.izip(*file_handlers):
sys.stdout.write(''.join(lines))
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
nexts = cycle(iter(it).next for it in iterables)
while pending:
try:
for next in nexts:
yield next()
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
sys.stdout.writelines(roundrobin(*file_handlers))
与这里的其他答案相比:
- 文件在退出时关闭
- izip_longest不会在一个文件停止时停止
- 有效利用内存
或者,对于多个文件(文件名
是文件列表):
谢谢在该示例中,我如何在不同文件的n
行和n+
行之间放置一个空行(请参见“所需输出”)?@Frank:在每个循环结束时打印一行新行。循环的一次迭代是来自每个文件的一行。所以你的换行符会跟在sys.stdout后面只要把sys.stdout.write()
改成print()
@Franksys.stdout.write(''.join(lines)+“\n”)
谢谢,这很简单。还有一个问题:*
在*文件处理程序中做什么?我喜欢使用contextsOkay进行包含,但这只适用于预先指定数量的文件(这里是2个文件)。嘿,andrew,如果有更多的文件名,你觉得如何使它更具动态性?类似这样的:@Frank:看我之前的评论哦,那更好;我会偷取那个语法。不应使用map:o)
> cat foo
foo 1
foo 2
foo 3
foo 4
> cat bar
bar 1
bar 2
> cat interleave.py
from itertools import izip_longest
from contextlib import nested
with nested(open('foo'), open('bar')) as (foo, bar):
for line in (line for pair in izip_longest(foo, bar)
for line in pair if line):
print line.strip()
> python interleave.py
foo 1
bar 1
foo 2
bar 2
foo 3
foo 4
with nested(*(open(file) for file in filenames)) as handles:
for line in (line for tuple in izip_longest(*handles)
for line in tuple if line):
print line.strip()