Python 两个列表之间的公共元素比较
到目前为止,但似乎无法让它工作 有什么想法吗?使用集合交点、集合(列表1)和集合(列表2)Python 两个列表之间的公共元素比较,python,list,Python,List,到目前为止,但似乎无法让它工作 有什么想法吗?使用集合交点、集合(列表1)和集合(列表2) def common_elements(list1, list2): """ Return a list containing the elements which are in both list1 and list2 >>> common_elements([1,2,3,4,5,6], [3,5,7,9]) [3, 5] >>&g
def common_elements(list1, list2):
"""
Return a list containing the elements which are in both list1 and list2
>>> common_elements([1,2,3,4,5,6], [3,5,7,9])
[3, 5]
>>> common_elements(['this','this','n','that'],['this','not','that','that'])
['this', 'that']
"""
for element in list1:
if element in list2:
return list(element)
请注意,结果列表可能与原始列表的顺序不同。和建议的解决方案通常会告诉您应该如何以Pythonic的方式完成,但我认为您也可以从了解解决方案不起作用的原因中获益。问题是,一旦在两个列表中找到第一个公共元素,就只返回单个元素。通过创建
结果
列表并收集该列表中的公共元素,可以修复您的解决方案:
>>> def common_elements(list1, list2):
... return list(set(list1) & set(list2))
...
>>>
>>> common_elements([1,2,3,4,5,6], [3,5,7,9])
[3, 5]
>>>
>>> common_elements(['this','this','n','that'],['this','not','that','that'])
['this', 'that']
>>>
>>>
使用列表理解的更短版本:
def common_elements(list1, list2):
result = []
for element in list1:
if element in list2:
result.append(element)
return result
但是,正如我所说的,这是一种非常低效的方法——Python的内置集类型在内部用C实现时效率更高。前面的答案都是为了找到唯一的公共元素,但无法解释列表中的重复项。如果希望公共元素的编号与列表中的公共元素相同,可以使用以下一行:
def common_elements(list1, list2):
return [element for element in list1 if element in list2]
只有当您希望任何元素的计算方法为False
1)时,才需要或True
部分1
保存列表1是字典,然后迭代列表2中的每个元素
l2, common = l2[:], [ e for e in l1 if e in l2 and (l2.pop(l2.index(e)) or True)]
寻找共同和不同的要素:
2) 方法2
使用集
def findarrayhash(a,b):
h1={k:1 for k in a}
for val in b:
if val in h1:
print("common found",val)
del h1[val]
else:
print("different found",val)
for key in h1.iterkeys():
print ("different found",key)
您还可以使用集合并在一行中获得共性:从其中一个集合中减去包含差异的集合
def findarrayset(a,b):
common = set(a)&set(b)
diff=set(a)^set(b)
print list(common)
print list(diff)
您可以使用一个简单的列表:
A = [1,2,3,4]
B = [2,4,7,8]
commonalities = set(A) - (set(A) - set(B))
Set是解决这个问题的另一种方法
x=[1,2,3,4]
y=[3,4,5]
common = [i for i in x if i in y]
common: [3,4]
使用发电机:
a = [3,2,4]
b = [2,3,5]
set(a)&set(b)
{2, 3}
这里的优点是,即使在使用大型列表或其他大型iterables时,也会以恒定的时间(几乎是瞬间)返回
比如说,
common = (x for x in list1 if x in list2)
对于列表1和列表2的这些值,这里的所有其他答案都需要很长时间
然后,您可以使用
list1 = list(range(0,10000000))
list2=list(range(1000,20000000))
common = (x for x in list1 if x in list2)
我比较了每个答案提到的每个方法。目前,我使用python 3.6.3实现此实现。这是我使用的代码:
for i in common: print(i)
如果您运行这段代码,您可以看到,如果您使用list或generator(如果您在generator上迭代,而不仅仅是使用它。我是在强制generator打印其长度时这样做的),您将获得几乎相同的性能。但如果您使用set,您将获得更好的性能。此外,如果您使用交集方法,您将获得更好的性能。我的计算机中每种方法的结果如下所示:
<代码>通用元素< /代码>将是NUBY数组:<代码>(3 5)< /C> > /P> < P>这里有解决方案,在O(L1+L2)中不计算重复项,以及考虑重复项的慢解(至少O(L1*L2),但可能更昂贵)。 所以我想我应该添加一个O(l1log(l1)+l2(log(l2))解决方案。如果列表已经排序,这尤其有用
import numpy as np
list1 = [1, 2, 3, 4, 5, 6]
list2 = [3, 5, 7, 9]
common_elements = np.intersect1d(list1, list2)
print(common_elements)
def common_elems_与_repeats(第一个_列表,第二个_列表):
第一个列表=已排序(第一个列表)
第二个列表=已排序(第二个列表)
标记_first=0
标记_秒=0
公共=[]
当marker_firstsecond_list[marker_second]:
标记_秒+=1
其他:
标记_first+=1
返回公共
另一个更快的解决方案包括从列表1生成一个item->count映射,并在更新映射和计数DUP的同时遍历列表2。不需要排序。需要额外的内存,但从技术上讲是O(l1+l2).+1但我个人使用了frozenset,因为它是不可变的,因此可以用作字典键等。这将返回/unique/common元素,但不会返回任何可能存在的重复元素。@SilentGhost。如何从两个列表中获取匹配元素的数量。在本例中,它是2。@Poka len(列表(set(list1)。交叉点(list2)))仅供参考。这肯定比Tamás提出的解决方案快,但对于我在本页结束时看到的用例,为后过滤元素保留元素的原始顺序很重要。此方法会丢失顺序,而列表理解方法会保留顺序。如果有人需要,这一点很重要来考虑一下。谢谢。谢谢你的帮助。了解我哪里出错了,下一步该做什么。还有一种方法可以保持这样的顺序吗?这两种方法都很好。注意:上述方法只适用于大小相同的列表。如果您像我一样处理大小不等的列表,那么您需要在调用函数之前评估基于len()的顺序:list1=[2,2,2],list2[2,3]->[2,2,2]list1=[2,3],list2[2,2,2]->[2]非常棒的解决方案,如果有一点小的话,这似乎是最彻底的解决方案,如果应该选择的答案的话!我假设它也适用于不平等列表。此外,大多数解决方案使用的
set
不稳定(即订单丢失)。此解决方案的运行时间至少为O(len(l1)*len(l2))(这不考虑pop和索引(e)的成本)。嗨,您可以添加一些关于计划如何使用代码的详细信息吗?如果这是为了完成一项任务,那么最好选择一种封装“Pythonic”方式的解决方案。然而,如果您关心效率,那么“Pythonic”方式不太可能是最有效的解决方案。就这些细节向我们提供建议将有助于解决您的问题
import time
import random
from decimal import Decimal
def method1():
common_elements = [x for x in li1_temp if x in li2_temp]
print(len(common_elements))
def method2():
common_elements = (x for x in li1_temp if x in li2_temp)
print(len(list(common_elements)))
def method3():
common_elements = set(li1_temp) & set(li2_temp)
print(len(common_elements))
def method4():
common_elements = set(li1_temp).intersection(li2_temp)
print(len(common_elements))
if __name__ == "__main__":
li1 = []
li2 = []
for i in range(100000):
li1.append(random.randint(0, 10000))
li2.append(random.randint(0, 10000))
li1_temp = list(set(li1))
li2_temp = list(set(li2))
methods = [method1, method2, method3, method4]
for m in methods:
start = time.perf_counter()
m()
end = time.perf_counter()
print(Decimal((end - start)))
import numpy as np
list1 = [1, 2, 3, 4, 5, 6]
list2 = [3, 5, 7, 9]
common_elements = np.intersect1d(list1, list2)
print(common_elements)
def common_elems_with_repeats(first_list, second_list):
first_list = sorted(first_list)
second_list = sorted(second_list)
marker_first = 0
marker_second = 0
common = []
while marker_first < len(first_list) and marker_second < len(second_list):
if(first_list[marker_first] == second_list[marker_second]):
common.append(first_list[marker_first])
marker_first +=1
marker_second +=1
elif first_list[marker_first] > second_list[marker_second]:
marker_second += 1
else:
marker_first += 1
return common