Python 计算两个列表之间重复项的最佳方法

Python 计算两个列表之间重复项的最佳方法,python,optimization,count,duplicates,Python,Optimization,Count,Duplicates,我看过一些帖子,其中介绍了如何从两个独特的列表中计算重复项(列表本身没有重复项),但对于如何为其他列表计算重复项,这不是一个好的解决方案,因此我自己提出了一些解决方案,但我怀疑它们是否得到了很好的优化 我的第一个版本: def version1(lst1,lst2): lst = list(set(lst1)) return sum(min(lst1.count(lst[i]), lst2.count(lst[i])) for i in range(len(lst))) 第二版

我看过一些帖子,其中介绍了如何从两个独特的列表中计算重复项(列表本身没有重复项),但对于如何为其他列表计算重复项,这不是一个好的解决方案,因此我自己提出了一些解决方案,但我怀疑它们是否得到了很好的优化

我的第一个版本:

def version1(lst1,lst2):
    lst = list(set(lst1))
    return sum(min(lst1.count(lst[i]), lst2.count(lst[i])) for i in range(len(lst)))
第二版:

def version2(lst1,lst2):
    lst = [i for n,i in enumerate(lst1) if i not in lst1[:n]]
    return sum(min(lst1.count(lst[i]), lst2.count(lst[i])) for i in range(len(lst)))
def version3(lst1,lst2):
    lst = list(dict.fromkeys(lst1).keys())
    return sum(min(lst1.count(lst[i]), lst2.count(lst[i])) for i in range(len(lst)))
第三版:

def version2(lst1,lst2):
    lst = [i for n,i in enumerate(lst1) if i not in lst1[:n]]
    return sum(min(lst1.count(lst[i]), lst2.count(lst[i])) for i in range(len(lst)))
def version3(lst1,lst2):
    lst = list(dict.fromkeys(lst1).keys())
    return sum(min(lst1.count(lst[i]), lst2.count(lst[i])) for i in range(len(lst)))
速度测试:

import random

lst1 = [random.randint(0,101) for i in range(0,10000)]
lst2 = [random.randint(0,101) for i in range(0,10000)]

from timeit import default_timer as timer

print("first result:",end=" ")
START = timer()
print(version1(lst1,lst2))
END = timer()
print("first time:",END-START)

print("second result:", end=" ")
START = timer()
print(version2(lst1,lst2))
END = timer()
print("second time:",END-START)

print("third result:", end=" ")
START = timer()
print(version3(lst1,lst2))
END = timer()
print("third time:",END-START)
版本2的分数始终低于1和3,但是版本1在列表本身中包含大量重复项的列表中得分更高,而版本3在列表本身中没有大量重复项的列表中得分更高

我想知道是否有人知道更好的方法。您可以使用哪个支持
&
操作:

>>> from collections import Counter
>>> Counter([1,2,2,4]) & Counter([2,2,3,4]) # {2:2, 1:1, 4:1} AND {2:2, 3:1, 4:1}
Counter({2: 2, 4: 1})
>>> sum(_.values())
3

更新

这是修改后的
version1
。您无需将
set
转换回
list
即可使用索引访问项目;只需迭代项目:

def version1_modified(lst1, lst2):
    return sum(min(lst1.count(x), lst2.count(x)) for x in set(lst1))
您可以使用哪些支持
操作:

>>> from collections import Counter
>>> Counter([1,2,2,4]) & Counter([2,2,3,4]) # {2:2, 1:1, 4:1} AND {2:2, 3:1, 4:1}
Counter({2: 2, 4: 1})
>>> sum(_.values())
3

更新

这是修改后的
version1
。您无需将
set
转换回
list
即可使用索引访问项目;只需迭代项目:

def version1_modified(lst1, lst2):
    return sum(min(lst1.count(x), lst2.count(x)) for x in set(lst1))

@Tristan,
set
将忽略重复的项目(通过只计算重复的项目一次),这不是OP想要的。@Tristan,
set
将忽略重复的项目(通过只计算重复的项目一次),这不是OP想要的。@nomis6432,它以给定的速度测试运行得很快@nomis6432,我更新了答案以包含另一个版本(版本1已修改)thnx此版本是最快的。@nomis6432,它在给定的速度测试中运行得很快@在nomis6432中,我更新了答案以包含另一个版本(版本1已修改),该版本是最快的。