Je sais comment obtenir une intersection de deux listes plates:
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)
Mais quand je dois trouver une intersection pour des listes imbriquées, mes problèmes commencent:
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]]
Au final, j'aimerais recevoir:
c3 = [[13,32],[7,13,28],[1,6]]
Pouvez-vous me donner un coup de main avec ça?
en relation
python
list
intersection
elfuego1
la source
la source
Réponses:
Si tu veux:
Alors voici votre solution pour Python 2:
En Python 3
filter
retourne un itérable au lieu delist
, vous devez donc encapsuler lesfilter
appels aveclist()
:Explication:
La partie filtre prend l'élément de chaque sous-liste et vérifie s'il se trouve dans la liste source c1. La compréhension de la liste est exécutée pour chaque sous-liste en c2.
la source
filter(set(c1).__contains__, sublist)
pour l'efficacité. btw, l'avantage de cette solution est qu'ellefilter()
préserve les types de chaînes et de tuples.c3 = [[x for x in sublist if x in c1] for sublist in c2]
Vous n'avez pas besoin de définir l'intersection. C'est déjà une partie de première classe de l'ensemble.
la source
set(b1) & set(b2)
? IMO son nettoyant pour utiliser l'opérateur.set
entraînera un code plus rapide de plusieurs ordres de grandeur. Voici un exemple de benchmark®: gist.github.com/andersonvom/4d7e551b4c0418de3160Pour les personnes cherchant simplement à trouver l'intersection de deux listes, l'Asker a fourni deux méthodes:
Mais il existe une méthode hybride plus efficace, car vous n'avez qu'à effectuer une conversion entre liste / ensemble, par opposition à trois:
Cela fonctionnera en O (n), alors que sa méthode originale impliquant la compréhension de liste fonctionnera en O (n ^ 2)
la source
L'approche fonctionnelle:
et il peut être appliqué au cas plus général de 1+ listes
la source
set(*input_list[:1]).intersection(*input_list[1:])
. Version iterator (it = iter(input_list)
):reduce(set.intersection, it, set(next(it, [])))
. Les deux versions ne nécessitent pas de convertir toutes les listes d'entrée à définir. Ce dernier est plus efficace en mémoire.from functools import reduce
pour l'utiliser en Python 3. Ou mieux encore, utilisez unefor
boucle explicite .Version de compréhension de liste pure
Aplatir la variante:
Variante imbriquée:
la source
L'opérateur & prend l'intersection de deux ensembles.
la source
Une façon pythonique de prendre l'intersection de 2 listes est:
la source
Vous devriez aplatir en utilisant ce code (extrait de http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks ), le code n'est pas testé, mais je suis presque sûr que cela fonctionne:
Après avoir aplati la liste, vous effectuez l'intersection de la manière habituelle:
la source
Depuis
intersect
sa définition, une compréhension de base des listes suffit:Amélioration grâce à la remarque de S. Lott et à la remarque associée de TM:
la source
Donné:
Je trouve que le code suivant fonctionne bien et peut-être plus concis si vous utilisez l'opération set:
Il a obtenu:
Si commande nécessaire:
nous avons:
Soit dit en passant, pour un style plus python, celui-ci est très bien aussi:
la source
Je ne sais pas si je suis en retard pour répondre à votre question. Après avoir lu votre question, j'ai trouvé une fonction intersect () qui peut fonctionner à la fois sur la liste et la liste imbriquée. J'ai utilisé la récursivité pour définir cette fonction, elle est très intuitive. J'espère que c'est ce que vous recherchez:
Exemple:
la source
Considérez-vous
[1,2]
croiser[1, [2]]
? Autrement dit, est-ce seulement les chiffres qui vous intéressent, ou la structure de la liste aussi?Si seuls les chiffres, étudiez comment "aplatir" les listes, puis utilisez la
set()
méthode.la source
Je cherchais également un moyen de le faire, et finalement ça a fini comme ça:
la source
la source
Nous pouvons utiliser des méthodes définies pour cela:
la source
Pour définir une intersection qui prend correctement en compte la cardinalité des éléments, utilisez
Counter
:la source
Voici une façon de définir
c3
qui n'implique pas d'ensembles:Mais si vous préférez utiliser une seule ligne, vous pouvez le faire:
C'est une compréhension de liste à l'intérieur d'une compréhension de liste, ce qui est un peu inhabituel, mais je pense que vous ne devriez pas avoir trop de mal à la suivre.
la source
Pour moi, c'est un moyen très élégant et rapide d'y arriver :)
la source
la liste plate peut être établie
reduce
facilement.Tout ce dont vous avez besoin pour utiliser l' initialiseur - troisième argument dans la
reduce
fonction.Le code ci-dessus fonctionne pour python2 et python3, mais vous devez importer le module de réduction sous
from functools import reduce
. Reportez-vous au lien ci-dessous pour plus de détails.pour python2
pour python3
la source
Un moyen simple de trouver la différence et l'intersection entre les itérables
Utilisez cette méthode si la répétition est importante
la source