在Python中从两个不同的文件一次读取两行

在Python中从两个不同的文件一次读取两行,python,Python,我有两个文件,如下所示: 文件1(以制表符分隔): A1 someinfo1 someinfo2 someinfo3 A1 someinfo1 someinfo2 someinfo3 B1 someinfo1 someinfo2 someinfo3 B1 someinfo1 someinfo2 someinfo3 文件2(以制表符分隔): A1新信息1新信息2新信息3 A1新信息1新信息2新信息3 B1新信息1新信息2新信息3 B1新信息1新信息2新信息3 我想同时阅读文件1中的两行(以A1和A

我有两个文件,如下所示:

文件1(以制表符分隔):

A1 someinfo1 someinfo2 someinfo3 A1 someinfo1 someinfo2 someinfo3 B1 someinfo1 someinfo2 someinfo3 B1 someinfo1 someinfo2 someinfo3 文件2(以制表符分隔):

A1新信息1新信息2新信息3 A1新信息1新信息2新信息3 B1新信息1新信息2新信息3 B1新信息1新信息2新信息3 我想同时阅读文件1中的两行(以A1和A1开头的行)和文件2中的两行(以A1和A1开头的行)。更清楚地说,我有两个要求:

1) Reading two lines from the same file 2) Read same two lines from the other file. 1) 从同一文件中读取两行 2) 从另一个文件中读取相同的两行。 准确地说,我想同时读取四行(两个文件中的两行(每个文件中的两行))数据

我在网上搜索,得到了一个代码,可以同时读取两行代码,但只能从一个文件中读取

with open(File1) as file1: for line1,line2 in itertools.izip_longest(*[file1]*2): 打开(文件1)作为文件1: 对于itertools.izip_longest(*[file1]*2)中的第1行和第2行: 此外,我还能够从两个文件中分别读取一行,如下所示:

for i,(line1,line2) in enumerate(itertools.izip(f1,f2)): print line1, line2 对于枚举(itertools.izip(f1,f2))中的i(第1行,第2行): 打印第1行,第2行 但我想做一些事情,比如:

伪代码:

for line1, line2 from file1 and line_1 and line_2 from file2: compare line1 with line2 compare line1 with line_1 compare line2 with line_1 compare line2 with line_2 对于文件1中的第1行、第2行以及文件2中的第_1行和第_2行: 比较第1行和第2行 将第1行与第1行进行比较 比较第2行和第1行 将第2行与第2行进行比较 我希望一个解决方案是线性时间的。所有文件都具有相同的行数,并且文件中连续行的第一列(主id)相同,而另一个文件遵循相同的顺序(请参见上面的示例)

谢谢

这个怎么样:

with open('a') as A, open('b') as B:
    while True:
        try:
            lineA1, lineA2, lineB1, lineB2 = next(A), next(A), next(B), next(B)
            # compare lines
            # ...
        except StopIteration:
            break

让我们看看如何把这些放在一起。第一:

with open(File1) as file1:
    for line1,line2 in itertools.izip_longest(*[file1]*2):
好的,去掉
for
循环,你就在
文件上有了一个每次两行的迭代器,对吗?因此,您可以对
file2
执行相同的操作。然后您可以
zip
将它们放在一起:

with open(File1) as file1, open(File2) as file2:
    f1 = itertools.izip_longest(*[file1]*2)
    f2 = itertools.izip_longest(*[file2]*2)
    for i,((f1_line1, f1_line2), (f2_line1, f2_line2)) in enumerate(itertools.izip(f1,f2)):
        # do stuff
但你真的不想这么做

首先,大多数人不会直观地阅读
izip_longest(*[file1]*2)
,并意识到它是成对分组的。把它作为一个函数。事实上,甚至不要自己编写函数;将
石斑鱼
直接从中取出

所以现在,它是:

with open(File1) as file1, open(File2) as file2:
    pairs1 = grouper(2, file1)
    pairs2 = grouper(2, file2)
    for i,((f1_line1, f1_line2), (f2_line1, f2_line2)) in enumerate(itertools.izip(f1,f2)):
        # do stuff

下,模式匹配可能是酷的,但是嵌套模式在复杂表达式的中间分解是有点太多了。因此,让我们将其分解,并通过再次从

itertools
文档中借用
flatten
来取消嵌套:

with open(File1) as file1, open(File2) as file2:
    pairs1 = grouper(2, file1)
    pairs2 = grouper(2, file2)
    zipped_pairs = itertools.izip(pairs1, pairs2)
    for i, zipped_pair in enumerate(zipped_pairs):
        f1_line1, f1_line2, f2_line1, f2_line2 = flatten(zipped_pair)
        # do stuff
此解决方案的优点是它是抽象和通用的,这意味着如果您以后决定需要5行或3个文件的组,那么更改是显而易见的

这种解决方案的缺点是它是抽象的和通用的,这意味着它不可能像做具体的等价物那样简单。(例如,如果你没有
zip
找到一对
grouper
s,你就不必
展平结果。)

您可以将行数设置为如下参数(
n

for lines in izip(*[file1]*n+[file2]*n):

现在,行将是一个包含
n*2
元素的元组

这里有一个泛化,允许任意数量的具有相同id列的连续行:

from itertools import groupby, izip, product

getid = lambda line: line.partition(" ")[0] # first space-separated column
same_id = lambda lines: groupby(lines, key=getid)

with open(File1) as file1, open(File2) as file2:
     for (id1, lines1), (id2, lines2) in izip(same_id(file1), same_id(file2)):
         if id1 != id2: 
            # handle error here
            break
         # compare all possible combinations
         for a, b in product(lines1, lines2): 
             compare(a, b)

@帕夫拉诺索夫:是的,我开始想“如何写得更通俗易懂……”谢谢阿巴内特的精彩解释。我想我现在更习惯使用izip功能。我更喜欢使用
next(A)
,等等。作为奖励,同样的代码也可以用于Python3Thanks-Pavel。我试过你的代码,它对我非常有效。非常感谢。为什么
比较line1和line2
而不是
比较line1和Lineu 2
,就像
line2
一样?
>>> from itertools import izip
>>> with open("file1") as file1, open("file2") as file2:
...     for a1, a2, b1, b2 in izip(file1, file1, file2, file2):
...         print a1, a2, b1, b2
... 
A1   someinfo1     someinfo2    someinfo3
A1   someinfo1     someinfo2    someinfo3
A1   newinfo1     newinfo2    newinfo3
A1   newinfo1     newinfo2    newinfo3

B1   someinfo1     someinfo2    someinfo3
B1   someinfo1     someinfo2    someinfo3
B1   newinfo1     newinfo2    newinfo3
B1   newinfo1     newinfo2    newinfo3
for lines in izip(*[file1]*n+[file2]*n):
from itertools import groupby, izip, product

getid = lambda line: line.partition(" ")[0] # first space-separated column
same_id = lambda lines: groupby(lines, key=getid)

with open(File1) as file1, open(File2) as file2:
     for (id1, lines1), (id2, lines2) in izip(same_id(file1), same_id(file2)):
         if id1 != id2: 
            # handle error here
            break
         # compare all possible combinations
         for a, b in product(lines1, lines2): 
             compare(a, b)