Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.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,我检查了这个,只有一个答案与我试图做的有关。我必须列出一些相似的元素,我想得到不匹配的元素 len(h) = 1973182 #h[0] = 'B00006J8F4F2', y[0] = 'B0075Y2X2GO6' len(y) = 656890 我在做什么 new\u list=[i为i,如果i不在y中,则在h中],但是这需要大约13分钟,有没有更快的方法 在参考“重复”问题中,我使用了相同的代码,我要寻找的是一种更快的方法。您可以使用它更有效地找到两个列表之间的差异。如果需要将顺序保留

我检查了这个,只有一个答案与我试图做的有关。我必须列出一些相似的元素,我想得到不匹配的元素

len(h) = 1973182  #h[0] = 'B00006J8F4F2', y[0] = 'B0075Y2X2GO6'
len(y) = 656890
我在做什么

new\u list=[i为i,如果i不在y中,则在h中]
,但是这需要大约13分钟,有没有更快的方法

在参考“重复”问题中,我使用了相同的代码,我要寻找的是一种更快的方法。

您可以使用它更有效地找到两个列表之间的差异。如果需要将顺序保留在原始列表中,可以使用带有
键的
排序

我们希望根据元素在原始列表中的外观对集合中的元素进行排序,因此一种方法是构建一个查找字典。我们可以使用
枚举。然后,我们只需要在字典中查找
函数:

d = {j:i for i,j in enumerate(h)}
new_list  = sorted(list((set(h) - set(y))), key = lambda x: d[x])

让我们举一个简单的例子:

y = range(5)
h = range(7)
d = {j:i for i,j in enumerate(h)}
sorted(list((set(h) - set(y))), key = lambda x: d[x])
# [5, 6]

时间安排-

import random
y = random.sample(range(1, 10001), 10000)
h = random.sample(range(1, 20001), 10000)

%timeit [i for i in h if i not in y]
# 1.28 s ± 37.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

def using_sets(a,b):
    d = {j:i for i,j in enumerate(a)}
    sorted(list((set(a) - set(b))), key = lambda x: d[x])

%timeit using_sets(h,y)
# 6.16 ms ± 373 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


因此有一个明显的改进,建议的方法执行速度快了200倍。

您链接的答案建议使用集合,因为它们使用哈希来快速查找。 使用列表和中的,如

new_list = [i for i in h if i not in y]
整个列表
y
需要每次检查
h
中的每个
i

您可以使用集合,但正如已经指出的,需要小心重复项丢失

您可以使用
计数器

from collections import Counter
比如说,这本书有两个列表

l1 = [1,1,2,3,4]
l2 = [3,3,4,5,6]
例如,可以使用fed将每个计数器输入

>>> Counter(l1)
Counter({1: 2, 2: 1, 3: 1, 4: 1})
>>> Counter(l2)
Counter({3: 2, 4: 1, 5: 1, 6: 1})
这只会遍历每个列表一次。 减去它们可以得到第一个,但不是第二个:

>>> Counter(l1)-Counter(l2)
Counter({1: 2, 2: 1})
元素告诉您想要什么

>>> diff = Counter(l1)-Counter(l2)
>>> list(diff.elements())
[1, 1, 2]

以编程方式使用,并在列表1中保持顺序和处理重复

def function(list1, list2):
    dic2={}   
    for i in list2:
        try:
            if i in dic2.keys():
                pass
        except KeyError:
            dic2[i]=1           

    result =[]
    for i in list1:
        try:
            if i in dic2.keys():
                pass
        except:
            result.append(i)
    return result



list1=[1,2,2,3]
list2=[3,4,5]

solution = function(list1,list2)
print(solution)
输出

[1, 2, 2]
使用@yatuh,y列表,这里是时间结果

%timeit function(h,y)
2.75 ms ± 22.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

您可以使用集合中的计数器类:

list1 = [1,1,2,3,4]
list2 = [3,3,4,5,6]

from collections import Counter
result = list((Counter(list1)-Counter(list2)).elements())

# [1, 1, 2]
或者,如果您想要相互排斥:

count1 = Counter(list1)
count2 = Counter(list2)
r = list((count1-count2+(count2-count1)).elements()) 

# [1, 1, 2, 3, 5, 6]

列表元素是唯一的吗?可能是重复的只是为了澄清-你说的“不匹配元素”是指第一个列表中不在第二个列表中的东西?或者不在其中的东西?在
y
中是否存在重复项?@yatu否,列表中的所有元素都是唯一的集合(h)-集合(y)将给出不在h中的h元素,可能对这两个列表都有要求这也将删除
h
中存在的任何重复项,即
h=[2,2]
h中不在h中的元素?这就产生了设置差异。哪一种方法更有效?
…如果我不在y中
是的,这是一个很好的观点@Sayse如果有重复的,它会。让askWell单独列出列表中的元素是唯一的@sayse感谢您指出这比
new\u list=sorted((set(h)-set(y)),key=h.index)快多少,因为我没有对对象进行排序,这将花费O(nlogn)时间,然后进行计算以保留索引,在这里,我只是对字典中list2的值进行了散列,所以O(1)是访问它的时间,O(n)是遍历list1的时间,所以复杂性变成了
O(n)
,@programmerwiz32查看当前的一个解决方案,检查速度,如果您发现它比接受和向上投票更好