我如何比较python和返回匹配的两个列表?

时间:2021-02-06 12:05:40

I want to take two lists and find the values that appear in both.

我想取两个列表,并找出两者都出现的值。

a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]

returnMatches(a, b)

would return [5], for instance.

例如,将返回[5]。

17 个解决方案

#1


310  

Not the most efficient one, but by far the most obvious way to do it is:

这不是最有效的方法,但到目前为止最明显的方法是:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
{5}

if order is significant you can do it with list comprehensions like this:

如果顺序是重要的,你可以这样做:

>>> [i for i, j in zip(a, b) if i == j]
[5]

(only works for equal-sized lists, which order-significance implies).

(只适用于同等规模的列表,这是更重要的含义)。

#2


268  

Use set.intersection(), it's fast and readable.

使用set.交集(),它是快速和可读的。

>>> set(a).intersection(b)
set([5])

#3


65  

A quick performance test showing Lutz's solution is the best:

快速的性能测试显示鲁兹的解决方案是最好的:

import time

def speed_test(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        for x in xrange(5000):
            results = func(*args, **kwargs)
        t2 = time.time()
        print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
        return results
    return wrapper

@speed_test
def compare_bitwise(x, y):
    set_x = frozenset(x)
    set_y = frozenset(y)
    return set_x & set_y

@speed_test
def compare_listcomp(x, y):
    return [i for i, j in zip(x, y) if i == j]

@speed_test
def compare_intersect(x, y):
    return frozenset(x).intersection(y)

# Comparing short lists
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

# Comparing longer lists
import random
a = random.sample(xrange(100000), 10000)
b = random.sample(xrange(100000), 10000)
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

These are the results on my machine:

这些是我机器上的结果:

# Short list:
compare_bitwise took 10.145 ms
compare_listcomp took 11.157 ms
compare_intersect took 7.461 ms

# Long list:
compare_bitwise took 11203.709 ms
compare_listcomp took 17361.736 ms
compare_intersect took 6833.768 ms

Obviously, any artificial performance test should be taken with a grain of salt, but since the set().intersection() answer is at least as fast as the other solutions, and also the most readable, it should be the standard solution for this common problem.

显然,任何人工的性能测试都应该有一定的含盐量,但是因为set().()的答案至少和其他的解决方案一样快,而且也是最易读的,所以它应该是这个常见问题的标准解决方案。

#4


39  

I prefer the set based answers, but here's one that works anyway

我更喜欢以集合为基础的答案,但这是一个有效的方法。

[x for x in a if x in b]

#5


11  

The easiest way to do that is to use sets:

最简单的方法是使用集合:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])

#6


10  

>>> s = ['a','b','c']   
>>> f = ['a','b','d','c']  
>>> ss= set(s)  
>>> fs =set(f)  
>>> print ss.intersection(fs)   
   **set(['a', 'c', 'b'])**  
>>> print ss.union(fs)        
   **set(['a', 'c', 'b', 'd'])**  
>>> print ss.union(fs)  - ss.intersection(fs)   
   **set(['d'])**

#7


9  

Quick way:

快捷方式:

list(set(a).intersection(set(b)))

#8


8  

Also you can try this,by keeping common elements in a new list.

您还可以尝试通过将公共元素保存在新列表中。

new_list = []
for element in a:
    if element in b:
        new_list.append(element)

#9


5  

Do you want duplicates? If not maybe you should use sets instead:

你想要复制吗?如果不是,你应该用set代替:


>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5]))
set([5])

#10


4  

Can use itertools.product too.

出现可以使用itertools。产品。

>>> common_elements=[]
>>> for i in list(itertools.product(a,b)):
...     if i[0] == i[1]:
...         common_elements.append(i[0])

#11


3  

You can use

您可以使用

def returnMatches(a,b):
       return list(set(a) & set(b))

#12


3  

You can use:

您可以使用:

a = [1, 3, 4, 5, 9, 6, 7, 8]
b = [1, 7, 0, 9]
same_values = set(a) & set(b)
print same_values

Output:

输出:

set([1, 7, 9])

#13


2  

another a bit more functional way to check list equality for list 1 (lst1) and list 2 (lst2) where objects have depth one and which keeps the order is:

另一种更实用的方法来检查列表1 (lst1)和列表2 (lst2)的列表相等,其中对象的深度为1,并且保持顺序为:

all(i == j for i, j in zip(lst1, lst2))   

#14


2  

a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]

lista =set(a)
listb =set(b)   
print listb.intersection(lista)   
returnMatches = set(['5']) #output 

print " ".join(str(return) for return in returnMatches ) # remove the set()   

 5        #final output 

#15


0  

If you want a boolean value:

如果你想要一个布尔值:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(b) == set(a)  & set(b) and set(a) == set(a) & set(b)
False
>>> a = [3,1,2]
>>> b = [1,2,3]
>>> set(b) == set(a)  & set(b) and set(a) == set(a) & set(b)
True

#16


0  

Using __and__ attribute method also works.

使用__and__属性方法也可行。

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a).__and__(set(b))
set([5])

or simply

或者简单地

>>> set([1, 2, 3, 4, 5]).__and__(set([9, 8, 7, 6, 5]))
set([5])
>>>    

#17


0  

The following solution works for any order of list items and also supports both lists to be different length.

下面的解决方案适用于任何列表项的顺序,并且支持两个列表的长度不同。

import numpy as np
def getMatches(a, b):
    matches = []
    unique_a = np.unique(a)
    unique_b = np.unique(b)
    for a in unique_a:
        for b in unique_b:
            if a == b:
                matches.append(a)
    return matches
print(getMatches([1, 2, 3, 4, 5], [9, 8, 7, 6, 5, 9])) # displays [5]
print(getMatches([1, 2, 3], [3, 4, 5, 1])) # displays [1, 3]

#1


310  

Not the most efficient one, but by far the most obvious way to do it is:

这不是最有效的方法,但到目前为止最明显的方法是:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
{5}

if order is significant you can do it with list comprehensions like this:

如果顺序是重要的,你可以这样做:

>>> [i for i, j in zip(a, b) if i == j]
[5]

(only works for equal-sized lists, which order-significance implies).

(只适用于同等规模的列表,这是更重要的含义)。

#2


268  

Use set.intersection(), it's fast and readable.

使用set.交集(),它是快速和可读的。

>>> set(a).intersection(b)
set([5])

#3


65  

A quick performance test showing Lutz's solution is the best:

快速的性能测试显示鲁兹的解决方案是最好的:

import time

def speed_test(func):
    def wrapper(*args, **kwargs):
        t1 = time.time()
        for x in xrange(5000):
            results = func(*args, **kwargs)
        t2 = time.time()
        print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
        return results
    return wrapper

@speed_test
def compare_bitwise(x, y):
    set_x = frozenset(x)
    set_y = frozenset(y)
    return set_x & set_y

@speed_test
def compare_listcomp(x, y):
    return [i for i, j in zip(x, y) if i == j]

@speed_test
def compare_intersect(x, y):
    return frozenset(x).intersection(y)

# Comparing short lists
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

# Comparing longer lists
import random
a = random.sample(xrange(100000), 10000)
b = random.sample(xrange(100000), 10000)
compare_bitwise(a, b)
compare_listcomp(a, b)
compare_intersect(a, b)

These are the results on my machine:

这些是我机器上的结果:

# Short list:
compare_bitwise took 10.145 ms
compare_listcomp took 11.157 ms
compare_intersect took 7.461 ms

# Long list:
compare_bitwise took 11203.709 ms
compare_listcomp took 17361.736 ms
compare_intersect took 6833.768 ms

Obviously, any artificial performance test should be taken with a grain of salt, but since the set().intersection() answer is at least as fast as the other solutions, and also the most readable, it should be the standard solution for this common problem.

显然,任何人工的性能测试都应该有一定的含盐量,但是因为set().()的答案至少和其他的解决方案一样快,而且也是最易读的,所以它应该是这个常见问题的标准解决方案。

#4


39  

I prefer the set based answers, but here's one that works anyway

我更喜欢以集合为基础的答案,但这是一个有效的方法。

[x for x in a if x in b]

#5


11  

The easiest way to do that is to use sets:

最简单的方法是使用集合:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])

#6


10  

>>> s = ['a','b','c']   
>>> f = ['a','b','d','c']  
>>> ss= set(s)  
>>> fs =set(f)  
>>> print ss.intersection(fs)   
   **set(['a', 'c', 'b'])**  
>>> print ss.union(fs)        
   **set(['a', 'c', 'b', 'd'])**  
>>> print ss.union(fs)  - ss.intersection(fs)   
   **set(['d'])**

#7


9  

Quick way:

快捷方式:

list(set(a).intersection(set(b)))

#8


8  

Also you can try this,by keeping common elements in a new list.

您还可以尝试通过将公共元素保存在新列表中。

new_list = []
for element in a:
    if element in b:
        new_list.append(element)

#9


5  

Do you want duplicates? If not maybe you should use sets instead:

你想要复制吗?如果不是,你应该用set代替:


>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5]))
set([5])

#10


4  

Can use itertools.product too.

出现可以使用itertools。产品。

>>> common_elements=[]
>>> for i in list(itertools.product(a,b)):
...     if i[0] == i[1]:
...         common_elements.append(i[0])

#11


3  

You can use

您可以使用

def returnMatches(a,b):
       return list(set(a) & set(b))

#12


3  

You can use:

您可以使用:

a = [1, 3, 4, 5, 9, 6, 7, 8]
b = [1, 7, 0, 9]
same_values = set(a) & set(b)
print same_values

Output:

输出:

set([1, 7, 9])

#13


2  

another a bit more functional way to check list equality for list 1 (lst1) and list 2 (lst2) where objects have depth one and which keeps the order is:

另一种更实用的方法来检查列表1 (lst1)和列表2 (lst2)的列表相等,其中对象的深度为1,并且保持顺序为:

all(i == j for i, j in zip(lst1, lst2))   

#14


2  

a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]

lista =set(a)
listb =set(b)   
print listb.intersection(lista)   
returnMatches = set(['5']) #output 

print " ".join(str(return) for return in returnMatches ) # remove the set()   

 5        #final output 

#15


0  

If you want a boolean value:

如果你想要一个布尔值:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(b) == set(a)  & set(b) and set(a) == set(a) & set(b)
False
>>> a = [3,1,2]
>>> b = [1,2,3]
>>> set(b) == set(a)  & set(b) and set(a) == set(a) & set(b)
True

#16


0  

Using __and__ attribute method also works.

使用__and__属性方法也可行。

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a).__and__(set(b))
set([5])

or simply

或者简单地

>>> set([1, 2, 3, 4, 5]).__and__(set([9, 8, 7, 6, 5]))
set([5])
>>>    

#17


0  

The following solution works for any order of list items and also supports both lists to be different length.

下面的解决方案适用于任何列表项的顺序,并且支持两个列表的长度不同。

import numpy as np
def getMatches(a, b):
    matches = []
    unique_a = np.unique(a)
    unique_b = np.unique(b)
    for a in unique_a:
        for b in unique_b:
            if a == b:
                matches.append(a)
    return matches
print(getMatches([1, 2, 3, 4, 5], [9, 8, 7, 6, 5, 9])) # displays [5]
print(getMatches([1, 2, 3], [3, 4, 5, 1])) # displays [1, 3]