我有两个csv文件,每个都是这种格式,
file1
zip name score
23431 david 12
23231 rob 45
33441 hary 23
98901 rgrg 55
file2
zip1 name1 score1
23433 david 12
23245 stel 45
33478 hary 23
98988 rob 55
12121 jass 33
我有一个名单,如下所示
lista = ['harry', 'rob', 'wine', 'david', 'jass']
最终的csv文件应该如下所示:
name zip score zip1 score1
harry x x x x
rob 23231 45 98988 55
wine x x x x
david 23431 12 23433 12
jass x x 12121 33
这意味着,如果列表中的任何名称位于任何一个csv文件中,那么我们应该将它包含在新的csv文件中,以及它的zip和分数。否则我们应该在其中打印'x'。
这是我到目前为止所做的:
import csv
with open('file1.csv', 'r') as input1, open('file2.csv', 'r') as input2, open('merge_final.csv', 'w') as output:
writer = csv.writer(output)
reader1 = csv.reader(input1)
eader2 = csv.reader(input2)
lista = ['harry', 'rob', 'wine', 'david', 'jass']
writer.writerow(['name','zip','score','zip1','score'])
for i in lista:
for row in list(reader1):
rev = row[1]
if i in rev:
score = row[2]
zip = row[0]
else:
score = 'x'
zip = 'x'
for row in list(reader2):
rev = row[1]
if i in rev:
score1 = row[2]
zip1 = row[0]
else:
score1 = 'x'
zip1 = 'x'
writer.writerow([i, score, zip, score1, zip1])
此代码未按预期工作。这是我使用此代码获得的输出。
name zip score zip1 score1
harry x x x x
rob x x x x
wine x x x x
david x x x x
jass x x x x
即使认为有许多常见的单词,只有'x'才能在最终合并的csv文件中打印出来。我认为问题在于循环。但是,我似乎没有弄清楚这个问题。
首先,list(readerX)
的第一次调用耗尽了文件句柄的迭代器。
其次,rev
本来应该是name
,所以检查平等不包含:if name == rev
。
第三,除了每个文件中的姓氏之外,你大多得到'x',因为你将文件迭代到最后,只有最后一行才真正重要。一旦找到名称,就应该break
内部循环,但只有在迭代整个文件而没有找到名称后才设置默认值。
此外,重复迭代这两个文件在性能方面是非常糟糕的。您最好将两个文件加载到永久数据结构中,使用更快的查找,如名称为键的嵌套dict
:
d1 = {row[1]: {'zip': row[0], 'score': row[2]} for row in reader1}
d2 = {row[1]: {'zip': row[0], 'score': row[2]} for row in reader2}
# {'david': {'zip': 23431, 'score: 12, ...}
for name in lista:
if name in d1 or name in d2:
writer.writerow([
name,
d1.get(name, {}).get('zip', 'x'),
d1.get(name, {}).get('score', 'x'),
d2.get(name, {}).get('zip', 'x'),
d2.get(name, {}).get('score', 'x'),
])
要使您自己的方法工作,请按以下方式进行更改,但请注意,由于嵌套循环,这对于较大的数据具有可怕的性能:
# next(reader1) # skip the header line if necessary
lst1 = list(reader1) # load all the data into a list beforehand ...
for i in lista:
for row in lst1: # ... that you can repeatedly iterate
rev = row[1]
if i == rev: # compare for equality
score = row[2]
zip = row[0]
break # <- you found the name, so end the loop!
else: # note the indentation: this is a for-else-loop, not an if-else
# the else-part is only executed if the for loop was NOT break'ed
score = 'x'
zip = 'x'
您是否认为将两个文件读入单个嵌套字典会更好,其中名称将是键,值将是带有键'zip,'zip1','score'和'score1'的字典?
{'hary' :
{'zip1':33478,
'zip':33441 ,
'score':23,
'score1':23 }
}
然后遍历列表并打印“x”以查找不存在的键
上面代码中的错误: