Quero pegar duas listas e encontrar os valores que aparecem em ambas.
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
returnMatches(a, b)
retornaria [5], por exemplo.
Quero pegar duas listas e encontrar os valores que aparecem em ambas.
a = [1, 2, 3, 4, 5]
b = [9, 8, 7, 6, 5]
returnMatches(a, b)
retornaria [5], por exemplo.
Respostas:
Não é a mais eficiente, mas a maneira mais óbvia de fazer isso é:
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
{5}
se a ordem for significativa, você poderá fazê-lo com compreensões de lista como esta:
>>> [i for i, j in zip(a, b) if i == j]
[5]
(funciona apenas para listas de tamanho igual, o que implica significado de ordem).
&) ou set(a).intersection(b)será tão rápida ou mais rápida que a compreensão da lista.
set(a) & set(b)?
Use set.intersection () , é rápido e legível.
>>> set(a).intersection(b)
set([5])
bool(set(a).intersection(b))para TrueouFalse
differenceou union.
.intersection()vs &?
Um teste rápido de desempenho mostrando a solução da Lutz é o melhor:
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)
Estes são os resultados na minha máquina:
# 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
Obviamente, qualquer teste de desempenho artificial deve ser feito com um grão de sal, mas como a set().intersection()resposta é pelo menos tão rápida quanto as outras soluções e também a mais legível, deve ser a solução padrão para esse problema comum.
setpartir de um existente listnão removerá nada do original list. Se você deseja que uma lógica especial manipule duplicatas em uma lista, acho que você precisará fazer uma nova pergunta, porque a resposta precisará ser específica de como você deseja que as duplicatas sejam manipuladas.
Eu prefiro as respostas baseadas em conjuntos, mas aqui está uma que funciona de qualquer maneira
[x for x in a if x in b]
A maneira mais fácil de fazer isso é usar conjuntos :
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a) & set(b)
set([5])
Atalho:
list(set(a).intersection(set(b)))
>>> 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'])**
Deseja duplicatas? Caso contrário, talvez você deva usar conjuntos:
>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5]))
set([5])
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
Também pode usar itertools.product.
>>> common_elements=[]
>>> for i in list(itertools.product(a,b)):
... if i[0] == i[1]:
... common_elements.append(i[0])
Você pode usar:
a = [1, 3, 4, 5, 9, 6, 7, 8]
b = [1, 7, 0, 9]
same_values = set(a) & set(b)
print same_values
Resultado:
set([1, 7, 9])
Se você deseja um valor booleano:
>>> 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
A solução a seguir funciona para qualquer ordem de itens da lista e também suporta as duas listas com comprimento diferente.
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]
np.intersect1d(list1, list2)
Usar o __and__método de atributo também funciona.
>>> a = [1, 2, 3, 4, 5]
>>> b = [9, 8, 7, 6, 5]
>>> set(a).__and__(set(b))
set([5])
ou simplesmente
>>> set([1, 2, 3, 4, 5]).__and__(set([9, 8, 7, 6, 5]))
set([5])
>>>
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.
&operador no set já é a resposta por SilentGhost na resposta aceita