Comment puis-je comparer deux listes en Python et retourner des correspondances

Je veux prendre deux listes et trouver les valeurs qui apparaissent dans les deux.

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

returnMatches(a, b)

Retournerait [5], par exemple.

264
demandé sur SilentGhost 2009-09-07 15:07:27

19 réponses

Pas le plus efficace, mais de loin la façon la plus évidente de le faire est:

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

Si l'ordre est significatif, vous pouvez le faire avec des compréhensions de liste comme ceci:

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

(ne fonctionne que pour les listes de taille égale, ce que la signification de l'ordre implique).

340
répondu SilentGhost 2009-09-07 11:10:46

Utilisez set.intersection(), c'est rapide et lisible.

>>> set(a).intersection(b)
set([5])
290
répondu Dennis 2013-10-01 07:11:14

Un test de performance rapide montrant la solution de Lutz est le meilleur:

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)

Ce sont les résultats sur ma 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

Évidemment, tout test de performance artificielle devrait être pris avec un grain de sel, mais puisque la réponse set().intersection() est au moins aussi rapide que les autres solutions, et aussi la plus lisible, elle devrait être la solution standard pour ce problème commun.

73
répondu Joshmaker 2014-06-05 08:31:53

Je préfère les réponses basées sur l'ensemble, mais en voici une qui fonctionne de toute façon

[x for x in a if x in b]
46
répondu SingleNegationElimination 2010-09-30 20:28:23

De La façon la plus simple de le faire est d'utiliser ensembles de:

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])
12
répondu Greg Hewgill 2009-09-07 11:10:53
>>> 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'])**
11
répondu setz 2013-05-11 22:09:55

Moyen Rapide:

list(set(a).intersection(set(b)))
9
répondu DisplacedAussie 2009-09-07 11:12:28

Vous pouvez également essayer ceci, en gardant les éléments communs dans une nouvelle liste.

new_list = []
for element in a:
    if element in b:
        new_list.append(element)
9
répondu mushfiq 2011-02-28 13:04:00

Voulez-vous des doublons? Si ce n'est pas le cas, vous devriez utiliser des ensembles à la place:


>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5]))
set([5])
5
répondu Timothy Pratley 2009-09-07 11:14:14

Peut utiliser itertools.produit trop.

>>> common_elements=[]
>>> for i in list(itertools.product(a,b)):
...     if i[0] == i[1]:
...         common_elements.append(i[0])
4
répondu Vikram S 2018-04-25 01:43:24

Vous pouvez utiliser

def returnMatches(a,b):
       return list(set(a) & set(b))
3
répondu Prabhu 2009-09-07 11:19:07

Vous pouvez utiliser:

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

Sortie:

set([1, 7, 9])
3
répondu Adnan Ghaffar 2016-01-06 11:07:15
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 
3
répondu Harish Verma 2017-07-19 22:00:07

Une autre façon un peu plus fonctionnelle de vérifier l'égalité de liste pour la liste 1 (lst1) et la liste 2 (lst2) où les objets ont une profondeur et qui garde l'ordre est:

all(i == j for i, j in zip(lst1, lst2))   
2
répondu itmatters 2016-07-04 08:41:34

Si vous voulez une valeur booléenne:

>>> 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
2
répondu Matheus Araujo 2017-03-06 06:49:33

La solution suivante fonctionne pour n'importe quel ordre d'éléments de liste et prend également en charge les deux listes pour avoir une longueur différente.

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
répondu Hafizur Rahman 2018-04-09 22:49:12

L'utilisation de la méthode d'attribut __and__ fonctionne également.

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

, Ou simplement

>>> set([1, 2, 3, 4, 5]).__and__(set([9, 8, 7, 6, 5]))
set([5])
>>>    
0
répondu Vikram S 2017-06-01 07:33:52

Je viens d'utiliser ce qui suit et cela a fonctionné pour moi:

group1 = [1, 2, 3, 4, 5]
group2 = [9, 8, 7, 6, 5]

for k in group1:
    for v in group2:
        if k == v:
            print(k)

Cela imprimerait alors 5 dans votre cas. Probablement pas une grande performance sage cependant.

0
répondu LRBrady 2018-09-04 19:26:04
you can | for set union and & for set intersection.
for example:

    set1={1,2,3}
    set2={3,4,5}
    print(set1&set2)
    output=3

    set1={1,2,3}
    set2={3,4,5}
    print(set1|set2)
    output=1,2,3,4,5

curly braces in the answer.
-1
répondu ravi tanwar 2018-07-18 19:06:09