在Python中比较两个CSV

时间:2014-01-21 07:29:27

标签: python

我在Python中格式化CSV以获得所需的结果,但我的代码似乎无法正常工作。

我有第一个格式的CSV文件:

2,a
1,a
4,a
5,a
3,a
1,a
3,b
2,b
1,a

格式为第二个CSV文件:

1,a,123
1,a,234
2,a,456
2,b,345
3,a,789
3,b,232
4,a,987

由于第一个CSV文件未排序,第二个CSV文件按照相对于第一列的递增顺序排序

我希望输出格式为:

2,a,456
1,a,123
4,a,987
5,a
3,a,789
1,a,234
3,b,232
2,b,345
1,a

如果在第二个CSV文件中找不到第一个CSV文件组合,则会打印出与第一个CSV相关的结果,例如,如果5,a不在第二个CSV文件中,则只有{{1}打印在其尊重的位置。第一个CSV文件包含许多重复项,而在第二个CSV文件中,每一行都是唯一的。

这是我的代码

5,a

first_csv和second_csv是我用以下代码读取CSV文件后创建的元组:

for (num,alpha) in first_csv:
    value_found = True
    for (num1,alpha1,num2) in second_csv:
        if (num == num1 and alpha == alpha1):
            csv_out +=  str(num) + ',' + str(alpha) + ',' + str(number)
            value_found = False
    if value_found:
        count+=1
        if count == 1:
            csv_out += str(num) + ',' + str(alpha)

但它没有打印出所需的输出,我在哪里做错了?

2 个答案:

答案 0 :(得分:3)

这会将第二个文件中的num2值收集到deque的字典中。找到匹配项后,将使用deque.popleft删除匹配项,以便按照与第二个文件中相同的顺序使用每个匹配项一次。

from collections import defaultdict, deque

with open('second_csv.csv') as f:
    next(f) #skip header
    dic = defaultdict(deque)
    for num1,alpha1,num2 in csv.reader(f, delimiter=','):
        dic[num1, alpha1].append(num2)

with open('first_csv.csv') as f, open('out.csv', 'wb') as fout:
    next(f) #skip header
    csv_out = csv.writer(fout)
    for num,alpha in csv.reader(f, delimiter=','):
        try:
            num2 = dic[num,alpha].popleft()
            csv_out.writerow([num,alpha,num2])
        except IndexError:
            csv_out.writerow([num,alpha])
  • deque保留您按append添加的项目顺序,并按popleft删除。
  • dict按键快速查找,可以是元组
  • defaultdict(deque)dict,当您访问丢失的密钥时会自动创建一个空deque,因此您可以append直接{。}}。

答案 1 :(得分:2)

这应该可以解决问题。请注意,对于first_csv上的每次迭代,最糟糕的情况是它必须迭代到第二个csv文件中数据左边的末尾(如果匹配则弹出行)。

import csv

with open("second_csv.csv") as in_file:
    reader = csv.reader(in_file)
    lookup = list(reader)

with open("first_csv.csv") as in_file, open('output.csv', 'wb') as out_file:
    reader = csv.reader(in_file)
    writer = csv.writer(out_file)
    for row in reader:
        for i, data in enumerate(lookup):
            if row == data[:2]:
                row = lookup.pop(i)
                break
        writer.writerow(row)

<强> output.csv

2,a,456
1,a,123
4,a,987
5,a
3,a,789
1,a,234
3,b,232
2,b,345
1,a