Eu sei como obter uma interseção de duas listas simples:
b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]
ou
def intersect(a, b):
return list(set(a) & set(b))
print intersect(b1, b2)
Mas quando tenho que encontrar a interseção para listas aninhadas, meus problemas começam:
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
No final, gostaria de receber:
c3 = [[13,32],[7,13,28],[1,6]]
Vocês podem me dar uma mão nisso?
Relacionado
python
list
intersection
elfuego1
fonte
fonte
Respostas:
Se você quiser:
Então aqui está sua solução para o Python 2:
No Python 3,
filter
retorna um iterável em vez delist
, portanto, é necessário agrupar asfilter
chamadas comlist()
:Explicação:
A parte do filtro pega o item de cada sub-lista e verifica se está na lista de fontes c1. A compreensão da lista é executada para cada sub-lista em c2.
fonte
filter(set(c1).__contains__, sublist)
para eficiência. Aliás, a vantagem dessa solução é quefilter()
preserva os tipos de cadeias e tuplas.c3 = [[x for x in sublist if x in c1] for sublist in c2]
Você não precisa definir interseção. Já é uma parte de primeira classe do set.
fonte
set(b1) & set(b2)
? OMI seu limpador para usar o operador.set
levará a códigos com ordens de magnitude mais rápidas. Aqui está um exemplo de benchmark®: gist.github.com/andersonvom/4d7e551b4c0418de3160Para pessoas que procuram encontrar a interseção de duas listas, o Asker forneceu dois métodos:
Mas há um método híbrido que é mais eficiente, porque você só precisa fazer uma conversão entre lista / conjunto, em vez de três:
Isso será executado em O (n), enquanto o método original que envolve compreensão de lista será executado em O (n ^ 2)
fonte
A abordagem funcional:
e pode ser aplicado ao caso mais geral de 1 ou mais listas
fonte
set(*input_list[:1]).intersection(*input_list[1:])
. Versão Iterator (it = iter(input_list)
):reduce(set.intersection, it, set(next(it, [])))
. Ambas as versões não precisam converter todas as listas de entrada para definir. Este último é mais eficiente em memória.from functools import reduce
para usá-lo no Python 3. Ou, melhor ainda, use umfor
loop explícito .Versão de compreensão pura da lista
Achatar variante:
Variante aninhada:
fonte
O operador & faz a interseção de dois conjuntos.
fonte
Uma maneira pitônica de fazer a interseção de 2 listas é:
fonte
Você deve nivelar usando este código (extraído de http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks ), o código não foi testado, mas tenho certeza de que funciona:
Depois de nivelar a lista, você faz a interseção da maneira usual:
fonte
Desde que
intersect
foi definido, uma compreensão básica da lista é suficiente:Melhoria graças à observação de S. Lott e à observação associada de TM.
fonte
Dado:
Acho que o código a seguir funciona bem e talvez seja mais conciso se estiver usando a operação set:
Tem:
Se pedido necessário:
obtemos:
A propósito, para um estilo mais python, este também é bom:
fonte
Não sei se estou atrasado em responder sua pergunta. Depois de ler sua pergunta, criei uma função intersect () que pode funcionar tanto na lista quanto na lista aninhada. Eu usei recursão para definir essa função, é muito intuitiva. Espero que seja o que você está procurando:
Exemplo:
fonte
Você considera
[1,2]
interceptar[1, [2]]
? Ou seja, são apenas os números importantes para você ou a estrutura da lista?Se apenas os números, investigue como "achatar" as listas e use o
set()
métodofonte
Eu também estava procurando uma maneira de fazer isso e, eventualmente, acabou assim:
fonte
fonte
Podemos usar métodos definidos para isso:
fonte
Para definir a interseção que leva em consideração corretamente a cardinalidade dos elementos, use
Counter
:fonte
Aqui está uma maneira de definir
c3
que não envolve conjuntos:Mas se você preferir usar apenas uma linha, poderá fazer o seguinte:
É uma compreensão de lista dentro de uma compreensão de lista, o que é um pouco incomum, mas acho que você não deve ter muita dificuldade em segui-la.
fonte
Para mim, esta é uma maneira muito elegante e rápida de fazê-lo :)
fonte
lista simples pode ser feita
reduce
facilmente.Tudo o que você precisa para usar o inicializador - terceiro argumento na
reduce
função.O código acima funciona para python2 e python3, mas você precisa importar o módulo de redução como
from functools import reduce
. Consulte o link abaixo para obter detalhes.para python2
para python3
fonte
Maneira simples de encontrar diferença e interseção entre iterables
Use este método se a repetição for importante
fonte