2009-09-07 4 views

Répondre

289

Pas le plus efficace, mais de loin le moyen le plus évident de le faire est la suivante:

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

si la commande est importante, vous pouvez le faire avec la liste compréhensions comme ceci:

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

(ne fonctionne que pour des listes de taille égale, ce qui implique l'importance de l'ordre).

+5

Une note de prudence, la compréhension de la liste est * pas * nécessairement l'option plus rapide. Pour les ensembles plus volumineux (où les performances sont les plus susceptibles d'avoir de l'importance), la comparaison de bits ('&') ou 'set (a) .intersection (b)' sera aussi rapide ou plus rapide que la compréhension de liste. – Joshmaker

+5

Une autre note de prudence: la compréhension de la liste trouve les valeurs qui apparaissent dans les deux aux mêmes positions (c'est ce que SilentGhost voulait dire par «l'ordre est significatif»). Les solutions d'intersection définies trouveront également des correspondances à DIFFÉRENTES positions. Ce sont des réponses à 2 questions tout à fait différentes ... (la question de l'op est ambiguë quant à ce qu'elle demande) – drevicko

+0

Comment faites-vous cela si vos listes sont des listes de listes à savoir a = [[0,0], [1, 0]] et b = [[2,3], [0,0]] – Schneems

11

La meilleure façon 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]) 
260

Utilisez set.intersection(), il est rapide et facile à lire.

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

Cette réponse a de bonnes performances algorithmiques, car une seule des listes (plus courte devrait être préférée) est transformée en ensemble pour une recherche rapide, et l'autre liste est parcourue en recherchant ses éléments dans l'ensemble. – u0b34a0f6ae

+3

'bool (set (a) .intersection (b))' pour 'True' ou' False' – Akshay

+0

Cette réponse est plus flexible et plus lisible, car les gens peuvent avoir besoin de ['difference'] (https: //docs.python. org/3/library/stdtypes.html # frozenset.difference) ou ['union'] (https://docs.python.org/3/library/stdtypes.html#frozenset.union). –

5

Voulez-vous que les doublons? Sinon, vous devriez peut-être utiliser des ensembles à la place:


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

Si vous voulez vraiment des listes, http://www.java2s.com/Code/Python/List/Functiontointersecttwolists.htm >>> intersectent ([1, 2, 3, 4, 5], [9, 8, 7, 6, 5]) [5] –

+0

Selon le doc - * ... exclut les constructions sujettes aux erreurs comme Set ('abc') & 'cbs' en faveur de l'ensemble plus lisible ('abc'). intersection ('cbs'). * - http://docs.python.org/library/sets.html –

3

Vous pouvez utiliser

def returnMatches(a,b): 
     return list(set(a) & set(b)) 
9
>>> 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'])** 
+0

La réponse acceptée ne fonctionne pas pour les listes contenant des chaînes. Celui-ci fait. – Antony

39

Je préfère les Définie en fonction des réponses, mais voici ce qui fonctionne de toute façon

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

également vous pouvez 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) 
64

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 

De toute évidence, tout test de performance artificielle doit être prise avec un grain de sel, mais depuis la réponse set().intersection() est au moins aussi vite que les autres solutions, et aussi le plus readab le, il devrait être la solution standard pour ce problème commun.

1

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

Comment cela est-il différent de la réponse acceptée il y a plus de 6 ans? – tom

+1

Eh bien, j'ai écrit le détail complet avec sortie et bon pour python débutant –

1

une autre un peu plus de manière fonctionnelle pour vérifier la liste d'égalité pour la liste 1 (lst1) et la liste 2 (LST2) où les objets ont une profondeur un et qui conserve la commande est:

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

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]) 
0

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 
0

utilisant __and__ méthode d'attribut 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]) 
>>>  
1
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 
+0

Alors que ce code peut répondre à la question, fournir un contexte supplémentaire concernant comment et/ou pourquoi il résout le problème permettrait d'améliorer la valeur à long terme de la réponse. –

Questions connexes