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.
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).
Utilisez set.intersection(), c'est rapide et lisible.
>>> set(a).intersection(b)
set([5])
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.
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]
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])
>>> 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'])**
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)
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])
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])
Vous pouvez utiliser
def returnMatches(a,b):
return list(set(a) & set(b))
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])
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
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))
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
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]
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])
>>>
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.
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.