2012-06-14 5 views
3

J'espère que je ne suis pas ici :-) dupliquantPython: moyen le plus efficace de filtrer une liste

Je me demande quel est le moyen le plus efficace de filtrer une liste de python. La tâche que j'ai en main est de trouver des éléments de liste qui n'apparaissent pas dans une autre liste.

Ma liste poing est une liste d'objets (sans détails inutiles):

Class A: 
    def __init__(self,item1, item2): 
     self.item1 = item1 
     self.item2 = item2 

plus tard, dans mon script, je suis l'analyse d'un fichier texte d'entrée et alimenter une list1 avec des données réelles (à la fois item1 et item2 les champs sont des chaînes)

il ya aussi une deuxième liste, list2 contenant juste une liste de chaînes correspondant à item1. Ce qui m'intéresse, ce sont les éléments dans list1item1 n'est pas dans le list2.
(list1 contient environ 3000 éléments, list2 est plus grand - CIRCA 60000 éléments.)

ma tentative de poing est tout à fait évident:

notMatched = list(itertools.ifilter(lambda x: x.item1 not in list2), list1)) 

maintenant, il fonctionne comme prévu, me donner exactement ce que Je veux, mais je me demande toujours si c'est la meilleure solution que je pourrais trouver. Une idée de quelqu'un?

Merci

+0

Votre solution bénéficierait de la conversion 'list2' un' set', mais vous constaterez probablement que la compréhension de la liste dans la réponse de Daren est plus rapide (et plus facile lire) –

Répondre

5

Faire list2 un ensemble. Cela permettra d'améliorer les performances de la recherche not in list2.

Vous pouvez probablement avec ceci:

set2 = set(list2) 
not_matched = [a for a in list1 if not a.item1 in set2] 
+0

Serait-il acceptable de convertir les deux listes à 'set' quand on obtient' not_matched'? par exemple 'not_matched = set (list1)^set (list2)' .. Y at-il des problèmes de performances ici? – msvalkon

+1

Cela ne fonctionnera pas, puisque 'list1' et' list2' sont de types différents. Je ne suis pas sûr si vous pourriez résoudre cela en écrivant un '.__ cmp__'. En outre, vous perdez la commande - en supposant que vous voulez le garder. En ce qui concerne les problèmes de performance: Créer un 'set' à partir d'une séquence * a * pour être O (n) au moins. L'intersection de deux 'set's est probablement aussi au moins O (n), donc, non, ça ne sera jamais plus rapide. Sauf si vous avez déjà les sets à portée de main ... –

+0

merci pour la clarification. – msvalkon

Questions connexes