web-dev-qa-db-fra.com

Comment comparer deux listes en python et renvoyer 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)

renverrait [5], par exemple.

289
tehryan

Ce n’est pas le plus efficace, mais le moyen le plus évident de le faire est de loin:

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

si l'ordre est important, vous pouvez le faire avec des listes comprenant:

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

(ne fonctionne que pour des listes de tailles égales, ce qui implique ordre de signification).

367
SilentGhost

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

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

Un test de performance rapide montrant que la solution de Lutz est la meilleure:

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)

Voici 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 artificiel doit être effectué 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 de ce problème courant .

81
Joshmaker

Je préfère les réponses basées sur l'ensemble, mais en voici une qui fonctionne quand même

[x for x in a if x in b]
52

Le moyen le plus simple de le faire est d’utiliser sets :

>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])
12
Greg Hewgill
>>> 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'])**
12
setz

Façon rapide:

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

Vous pouvez également essayer cela en conservant les éléments communs dans une nouvelle liste. 

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

Voulez-vous des doublons? Sinon, vous devriez plutôt utiliser des ensembles:


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

Peut aussi utiliser itertools.product.

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

Vous pouvez utiliser 

def returnMatches(a,b):
       return list(set(a) & set(b))
3
Prabhu
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
Harish Verma

une autre manière un peu plus fonctionnelle de vérifier l’égalité des listes pour les listes 1 (lst1) et 2 (lst2) où les objets ont une profondeur un et qui conserve l’ordre est:

all(i == j for i, j in Zip(lst1, lst2))   
3
itmatters

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
Adnan Ghaffar

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
Matheus Araujo

La solution suivante fonctionne pour n'importe quel ordre d'éléments de liste et prend également en charge la longueur des deux listes.

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
Hafizur Rahman

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 pourrait alors imprimer 5 dans votre cas. Ce n’est probablement pas une excellente performance.

0
LRBrady
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.
0
ravi tanwar

Utiliser 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
SuperNova