比较两个CSV文件并搜索类似的项目

ser*_*erk 14 python csv compare

所以我有两个我想要比较的CSV文件并获得类似项目的结果.第一个文件hosts.csv如下所示:

Path    Filename    Size    Signature
C:\     a.txt       14kb    012345
D:\     b.txt       99kb    678910
C:\     c.txt       44kb    111213
Run Code Online (Sandbox Code Playgroud)

第二个文件masterlist.csv如下所示:

Filename    Signature
b.txt       678910
x.txt       111213
b.txt       777777
c.txt       999999
Run Code Online (Sandbox Code Playgroud)

如您所见,行不匹配,并且masterlist.csv始终大于hosts.csv文件.我想要搜索的唯一部分是Signature部分.我知道这看起来像:

hosts[3] == masterlist[1]
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个解决方案,它将给我类似下面的内容(基本上是带有新的RESULTS列的hosts.csv文件):

Path    Filename    Size    Signature    RESULTS
C:\     a.txt       14kb    012345       NOT FOUND in masterlist
D:\     b.txt       99kb    678910       FOUND in masterlist (row 1)
C:\     c.txt       44kb    111213       FOUND in masterlist (row 2)
Run Code Online (Sandbox Code Playgroud)

我搜索的帖子,发现类似这样的东西在这里,但我不太明白它,因为我还在学习蟒蛇.

使用Python 2.6 编辑

Mar*_*ers 22

srgerg的答案极其低效,因为它以二次方式运行; 这是一个线性时间解决方案,使用Python 2.6兼容语法:

import csv

with open('masterlist.csv', 'rb') as master:
    master_indices = dict((r[1], i) for i, r in enumerate(csv.reader(master)))

with open('hosts.csv', 'rb') as hosts:
    with open('results.csv', 'wb') as results:    
        reader = csv.reader(hosts)
        writer = csv.writer(results)

        writer.writerow(next(reader, []) + ['RESULTS'])

        for row in reader:
            index = master_indices.get(row[3])
            if index is not None:
                message = 'FOUND in master list (row {})'.format(index)
            else:
                message = 'NOT FOUND in master list'
            writer.writerow(row + [message])
Run Code Online (Sandbox Code Playgroud)

这将生成一个字典,首先将签名从masterlist.csv行号映射到行号.字典中的查找占用一定的时间,使第二个循环超过hosts.csv行中的行数masterlist.csv.更不用说代码更简单了.

对于那些使用Python 3的人,上面只需要open()调整调用以在文本模式下打开(b从文件模式中删除),并且您想要添加new line=''以便CSV读取器可以控制行分隔符.您可能希望声明显式使用的编码,而不是依赖于系统默认(使用encoding=...).该master_indices映射可以借助字典理解建立({r[1]: i for i, r in enumerate(csv.reader(master))}).


srg*_*erg 13

编辑:当我的解决方案正常工作时,请查看下面的Martijn答案,以获得更有效的解决方案.

您可以在此处找到python CSV模块的文档.

您正在寻找的是这样的:

import csv

f1 = file('hosts.csv', 'r')
f2 = file('masterlist.csv', 'r')
f3 = file('results.csv', 'w')

c1 = csv.reader(f1)
c2 = csv.reader(f2)
c3 = csv.writer(f3)

masterlist = list(c2)

for hosts_row in c1:
    row = 1
    found = False
    for master_row in masterlist:
        results_row = hosts_row
        if hosts_row[3] == master_row[1]:
            results_row.append('FOUND in master list (row ' + str(row) + ')')
            found = True
            break
        row = row + 1
    if not found:
        results_row.append('NOT FOUND in master list')
    c3.writerow(results_row)

f1.close()
f2.close()
f3.close()
Run Code Online (Sandbox Code Playgroud)