简体   繁体   English

"两个列表的交集,包括重复项?"

[英]Intersection of two lists including duplicates?

>>> a = [1,1,1,2,3,4,4]
>>> b = [1,1,2,3,3,3,4]

[1,1,2,3,4]

Please note this is not the same question as this: Python intersection of two lists keeping duplicates Because even though there are three 1s in list a, there are only two in list b so the result should only have two.请注意,这与以下问题不同: Python 两个列表保持重复的交集因为即使列表 a 中有三个 1,但列表 b 中只有两个,所以结果应该只有两个。

Simple with no additional imports and easy to debug :)简单,无需额外导入且易于调试 :)

Disadvantage: The value of list b is changed.缺点:列表b的值改变了。 Work on a copy of b if you don't want to change b.如果您不想更改 b,请处理 b 的副本。

c = list()
for x in a:
    if x in b:
        b.remove(x)
        c.append(x)

The accepted solution posted using Counter is simple, but I think this approach using a dictionary will work too and can be faster -- even on lists that aren't ordered (that requirement wasn't really mentioned, but at least one of the other solutions assumes that is the case).使用 Counter 发布的公认解决方案很简单,但我认为这种使用字典的方法也可以工作并且可以更快 - 即使在未排序的列表上也是如此(该要求并未真正提及,但至少其中一个)解决方案假设是这种情况)。

a = [1, 1, 1, 2, 3, 4, 4]
b = [1, 1, 2, 3, 3, 3, 4]
    
def intersect(nums1, nums2):
    match = {}
    for x in a:
        if x in match:
            match[x] += 1
        else:
            match[x] = 1
            
    i = []
    for x in b:
        if x in match:
            i.append(x)
            match[x] -= 1
            if match[x] == 0:
                del match[x]

    return i

def intersect2(nums1, nums2):
    return list((Counter(nums1) & Counter(nums2)).elements())

timeit intersect(a,b)
100000 loops, best of 3: 3.8 µs per loop

timeit intersect2(a,b)
The slowest run took 4.90 times longer than the fastest. This could mean 
that an intermediate result is being cached.
10000 loops, best of 3: 20.4 µs per loop

This should also works.这也应该有效。

a = [1, 1, 1, 2, 3, 4, 4]
b = [1, 1, 2, 3, 3, 3, 4]
c = []
i, j = 0, 0
while i < len(a) and j < len(b):
    if a[i] == b[j]:
        c.append(a[i])
        i += 1
        j += 1
    elif a[i] > b[j]:
        j += 1
    else:
        i += 1

print(c) # [1, 1, 2, 3, 4]

This should also work:这也应该有效:

def list_intersect(lisA, lisB):
    """ Finds the intersection of 2 lists including common duplicates"""

    Iset = set(lisA).intersection(set(lisB))
    Ilis = []
    for i in Iset:
        num = min(lisA.count(i), lisB.count(i))
        for j in range(num):
            Ilis.append(i)
    return Ilis

This will do:这将做:

from itertools import chain
list(chain.from_iterable([(val,)*min(a.count(val), b.count(val)) for val in (set(a) & set(b))]))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM