我正在逐行比较 2 个文件
JSON中的一个喜欢这个:
{firstname: "xxx", lastname: "xxx"}
{firstname: "yyy", lastname: "yyy"}
csv 中的一个喜欢这个:
firstname;lastname;
xxx;xxx
yyy;yyy
两个列表都按名字排序,我创建了 2 个嵌套循环来存储索引和匹配计数,如下所示:
i = j = 0
chunks = []
while i < len(list_json):
matched = 0
while j < len(list_csv):
if list_json[i]['firstname'][0] < list_csv[j][0][0]:
j = 0
break
if ist_json[i]['firstname'] == list_csv[j][0]:
matched += 1
# more thing here
j += 1
chunck.append((i,matched)
我的问题是两个文件都在大约 1 M 行,而且需要太长(超过 24 小时(。 你有什么想法可以快速解决这个问题吗?
a = [{'firstname': "aaa", 'lastname': "bbb"},
{'firstname': "xxx", 'lastname': "xxx"},
{'firstname': "xxx", 'lastname': "yyy"},
{'firstname': "yyy", 'lastname': "xxx"},
{'firstname': "yyy", 'lastname': "yyy"},
]
b = [['xxx','xxx'],
['xxx','xxx'],
['yyy','yyy'],
['zzz','zzz']]
list_json = a
list_csv = b
您的一些逻辑错误,并且在错误的时间更改了索引。 我认为这可以解决您的解决方案。您的解决方案仅计算名字匹配项 - 我添加了名字和姓氏匹配的测试。
i = j = 0
chunks = []
f_and_l_chunks = []
while i < len(list_json):
matched = 0
f_and_l_matched = 0
fjson,ljson = list_json[i]['firstname'],list_json[i]['lastname']
while j < len(list_csv):
fcsv,lcsv = list_csv[j][0],list_csv[j][1]
#print(f'i:{i} j:{j} | {fjson},{fcsv}')
if fjson[0] < fcsv[0]: # sorted by first name so short circuit
break
if fjson == fcsv: # compare first only like your example
#print(' matched')
matched += 1
if (fjson,ljson) == (fcsv,lcsv): # compare first and last
f_and_l_matched += 1
j += 1
chunks.append((i,matched))
f_and_l_chunks.append((i,f_and_l_matched))
i += 1
j = 0
我很确定两个字符串之间的小于比较与比较第一个字符一样快。
if fjson[0] < fcsv[0]: # sorted by first name so short circuit
break
效率与
if fjson < fcsv: # sorted by first name so short circuit
break
看来我误解或没有彻底阅读你的问题。这是我的第一个答案,无关紧要,但我会留给后人。
从每个容器中获取名字,并使用 set 交集查找常见项。
import operator
afn = map(operator.itemgetter('firstname'),a)
bfn = map(operator.itemgetter(0),b)
common = set(afn).intersection(bfn)
>>> common
{'xxx', 'yyy'}
或者匹配名字和姓氏使用相同的过程。
from operator import itemgetter
anames = map(itemgetter('firstname','lastname'), a)
bnames = map(itemgetter(0,1),b)
common = set(anames).intersection(bnames)