Python同时逐行迭代两个文件

时间:2014-07-25 17:10:28

标签: python if-statement iteration string-matching readlines

我正在尝试比较两个文件中的列以查看值是否匹配,如果匹配,我想合并/连接该行的数据。我的问题是,当分别从两个文件中逐行阅读时,我无法让python一起迭代文件并寻找匹配。相反,它将在一个文件中正确迭代并多次迭代在第二个文件中的同一行...

过去我遇到过这个问题,但仍未找到解决方法。我知道缩进是一个问题,因为我通过使用"对于a中的行,对于b&#34中的行来弄乱循环。所以我认为我在下面尝试的东西会起作用,但它没有。我一直在寻找解决方案,但似乎没有人使用相同的方法,所以我想知道我是否完全偏离了如何做到这一点?任何人都可以解释什么是更好的方法来做到这一点,以及我的方法是否会起作用,如果没有,为什么不呢?谢谢,非常感谢!

这些是我的两个文件的格式,基本上我想比较两个文件中的列文件名,如果它们匹配,我想将这些行合并在一起。

file1:
cluster_id  hypothesis_id   filename    M1_name_offset  Orientation
1   71133076    unique_name_1.png   esc_sox2_Sox1_80_4  forward
1   50099120    unique_name_4.png   hb_cebpb_ETS1_139_7 forward
1   91895576    unique_name_11.png  he_tal1_at_AC_acptr_258_11  forward

file2:
Name                Cluster_No  Pattern     filename
esc_sox2_Sox1_80    Cluster1    AP1(1N)ETS      unique_name_4.png
hb_cebpb_ETS1_139   Cluster1    CREB(1N)ETS     unique_name_11.png
he_tal1_at_AC_acptr_258 Cluster2    ETS(-1N)ZIC     unique_name_3.png

我尝试过:

for aline in file1:
    motif1 = aline.split()[2]
    for bline in file2:
        motif2 = bline.split()[-1]
            if motif1 = motif2:
                print "match", aline, bline

我也尝试过:

for aline in file1:
    motif1 = aline.split()[2]
for bline in file2:
    motif2 = bline.split()[-1]
        if motif1 = motif2:
            print "match", aline, bline

我也尝试过使用字符串格式,但这并没有什么不同。第一种方式错误地迭代文件2,第二种方式没有给我任何输出。我已经玩了很多,并尝试了各种缩进和额外的位,但我很难过如何尝试修复它!请帮帮我:(

2 个答案:

答案 0 :(得分:4)

使用zip内置功能。<​​/ p>

with open(file1) as f1, open(file2) as f2:
    for line1, line2 in zip(f1, f2):
        motif1 = line1.split()[0]
        motif2 = line2.split()[0]
        ...

请注意zip在python2和python3中的行为有所不同。在python2中,使用itertools.izip会更有效。

答案 1 :(得分:1)

我假设您正在使用Python 3.这是一个很好的抽象,iterlines。它隐藏了打开,阅读,配对和关闭 n 文件的复杂性。请注意zip_longest的使用,这可以防止较长文件的末尾被静默丢弃。

def iterlines(*paths, fillvalue=None, **open_kwargs):
    files = []
    try:
        for path in paths:
            files.append(open(path, **open_kwargs))
        for lines in zip_longest(*files, fillvalue=fillvalue):
            yield lines
    finally:
        for file_ in files:
            with suppress():
                file_.close()

<强>用法

for line_a, line_b in iterlines('a.txt', 'b.txt'):
    print(line_a, line_b)

完整代码

from contextlib import suppress
from itertools import zip_longest


def iterlines(*paths, fillvalue=None, **open_kwargs):
    files = []
    try:
        for path in paths:
            files.append(open(path, **open_kwargs))
        for lines in zip_longest(*files, fillvalue=fillvalue):
            yield lines
    finally:
        for file_ in files:
            with suppress():
                file_.close()


for lines in iterlines('a.txt', 'b.txt', 'd.txt'):
    print(lines)