As respostas abaixo parecem erradas para mim. O que acontece se um número é repetido em qualquer lista, certamente você gostaria de saber que (?) (Por exemplo, digamos que as duas listas tenham '5' duas vezes) Qualquer solução que utilize conjuntos removerá imediatamente todos os itens repetidos e você perderá essa informação.
Uma nota de cautela, a compreensão da lista não é necessariamente a opção mais rápida. Para conjuntos maiores (onde é mais provável que o desempenho seja importante), a comparação bit a bit ( &) ou set(a).intersection(b)será tão rápida ou mais rápida que a compreensão da lista.
Joshmaker
24
Outra nota de cautela: a compreensão da lista encontra os valores que aparecem nas duas posições MESMAS (isto é o que SilentGhost quis dizer com "ordem é significativa"). As soluções de interseção definidas também encontrarão correspondências em posições DIFERENTES. Estes são respostas a 2 perguntas completamente diferentes ... (pergunta do OP é ambígua a respeito de que ele está pedindo)
drevicko
Como você faz isso se suas listas são listas de listas, ou seja, a = [[0,0], [1,0]] eb = [[2,3], [0,0]]
Schneems
3
Qual seria a complexidade temporal do primeiro exemplo set(a) & set(b)?
AdjunctProfessorFalcon
Observe que isso não funciona se os dois conjuntos estiverem vazios e você espera que a comparação seja aprovada. Então mude para "(conjunto (a) e conjunto (b)) ou (não a e não b)"
Essa resposta tem um bom desempenho algorítmico, pois apenas uma das listas (mais curta deve ser preferida) é transformada em um conjunto para pesquisa rápida e a outra lista é percorrida procurando seus itens no conjunto.
U0b34a0f6ae 7/09/09
18
bool(set(a).intersection(b))para TrueouFalse
Akshay
6
Essa resposta é mais flexível e legível, pois as pessoas podem precisar differenceou union.
Shihe Zhang #
E se eu tiver objetos como elementos da lista e desejar apenas correspondências parciais, ou seja, apenas alguns atributos tiverem que corresponder para que sejam considerados como objetos correspondentes?
CGFoX 22/03/19
Existe alguma diferença de desempenho para .intersection()vs &?
brandonbanks
106
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_testdef compare_bitwise(x, y):
set_x = frozenset(x)
set_y = frozenset(y)return set_x & set_y
@speed_testdef compare_listcomp(x, y):return[i for i, j in zip(x, y)if i == j]@speed_testdef 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 listsimport 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.
Set está realmente removendo repetições, portanto, no meu caso, não funcionará
rgralma 06/03
@rgralma criar um novo a 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.
Joshmaker 25/03
67
Eu prefiro as respostas baseadas em conjuntos, mas aqui está uma que funciona de qualquer maneira
De acordo com o doc - ... exclui construções propensas a erros como Set ('abc') e 'cbs' em favor do conjunto mais legível ('abc'). Intersection ('cbs'). - docs.python.org/library/sets.html
Aaron Newton
5
outra maneira um pouco mais funcional de verificar a igualdade de lista para a lista 1 (lst1) e a lista 2 (lst2) onde os objetos têm profundidade um e que mantém a ordem:
Embora esse código possa responder à pergunta, fornecer um contexto adicional sobre como e / ou por que resolve o problema melhoraria o valor a longo prazo da resposta.
Donald Duck
4
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])
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.
Respostas:
Não é a mais eficiente, mas a maneira mais óbvia de fazer isso é:
se a ordem for significativa, você poderá fazê-lo com compreensões de lista como esta:
(funciona apenas para listas de tamanho igual, o que implica significado de ordem).
fonte
&
) ouset(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.
fonte
bool(set(a).intersection(b))
paraTrue
ouFalse
difference
ouunion
..intersection()
vs&
?Um teste rápido de desempenho mostrando a solução da Lutz é o melhor:
Estes são os resultados na minha máquina:
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.fonte
set
partir de um existentelist
não removerá nada do originallist
. 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
fonte
A maneira mais fácil de fazer isso é usar conjuntos :
fonte
Atalho:
fonte
fonte
Além disso, você pode tentar fazer isso mantendo elementos comuns em uma nova lista.
fonte
Deseja duplicatas? Caso contrário, talvez você deva usar conjuntos:
fonte
outra maneira um pouco mais funcional de verificar a igualdade de lista para a lista 1 (lst1) e a lista 2 (lst2) onde os objetos têm profundidade um e que mantém a ordem:
fonte
fonte
Também pode usar itertools.product.
fonte
Você pode usar
fonte
Você pode usar:
Resultado:
fonte
Se você deseja um valor booleano:
fonte
A solução a seguir funciona para qualquer ordem de itens da lista e também suporta as duas listas com comprimento diferente.
fonte
np.intersect1d(list1, list2)
Usar o
__and__
método de atributo também funciona.ou simplesmente
fonte
fonte
&
operador no set já é a resposta por SilentGhost na resposta aceitaEu apenas usei o seguinte e funcionou para mim:
isso imprimiria 5 no seu caso. Provavelmente não é ótimo desempenho sábio embora.
fonte