什么是交织文本文件内容的最具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

问题:

如果我有一个文件列表,那么如何打印每个文件的第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(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()
@Frank
sys.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()