J'ai une liste A d'environ 62 000 numéros et une autre liste B d'environ 370 000. Je voudrais filtrer B pour qu'il ne contienne que des éléments de A. J'ai essayé quelque chose comme ceci:

A=[0,3,5,73,88,43,2,1]
B=[0,5,10,42,43,56,83,88,892,1089,3165]
C=[item for item in A if item in set(B)] 

Ce qui fonctionne, mais est évidemment très lent pour de si grandes listes car (je pense?) La recherche se poursuit dans tout le B, même lorsque l'élément a déjà été trouvé en B. Le script parcourt donc une liste de 370 000 éléments 62 000 fois .

Les éléments de A et B sont uniques (B contient une liste de valeurs uniques comprises entre 0 et 700 000 et A en contient un sous-ensemble unique), donc une fois que A [i] est trouvé dans B, la recherche peut s'arrêter. Les valeurs sont également en ordre croissant, si cela signifie quelque chose.

Y a-t-il un moyen de le faire plus rapidement?

3
Kingle 14 mars 2019 à 23:03

2 réponses

Meilleure réponse

Cela crée un nouveau set(B) pour chaque élément de A. À la place, utilisez le set.intersection intégré:

C = set(A).intersection(B)
7
Patrick Haugh 14 mars 2019 à 20:07

Pour être vraiment sûr que ce que j'ai fait est le plus rapide possible, je l'aurais fait:

A=[0,3,5,73,88,43,2,1]
B=[0,5,10,42,43,56,83,88,892,1089,3165]

B_filter = B.copy()
C = []
for item in A:
    if filter in B_filter:
        C.append(item)
        B_filter.pop(0) # B_filter is a list, and it's in ascending order so always the first

Si vous ne vous souciez pas de perdre votre liste B, vous pouvez simplement utiliser B au lieu de B_filter et ne pas déclarer B_filter, vous n'avez donc pas à copier un 370k grande liste.

0
Fukiyel 14 mars 2019 à 20:11