Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 两个列表之间的公共元素比较_Python_List - Fatal编程技术网

Python 两个列表之间的公共元素比较

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

到目前为止,但似乎无法让它工作

有什么想法吗?

使用集合交点、集合(列表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]
    >>> 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,您将获得更好的性能。此外,如果您使用交集方法,您将获得更好的性能。我的计算机中每种方法的结果如下所示:

  • 方法1:0.8150673999999974619413478649221360683441
  • 方法二:0.8329545000000001531148541289439890533685684
  • 方法3:0.0016547000000000089414697868051007390022277
  • 方法4:0.00102629999992944948867271887138485908508
  • 您可以使用以下方法解决此问题:


    <代码>通用元素< /代码>将是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