Как отфильтровать список на основе элементов другого списка в Python - PullRequest
3 голосов
/ 14 марта 2019

У меня есть список А из примерно 62 000 номеров, а другой список В из примерно 370 000. Я хотел бы отфильтровать B так, чтобы он содержал только элементы из A. Я попробовал что-то вроде этого:

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)] 

Что работает, но, очевидно, очень медленно для таких больших списков, потому что (я думаю?) Поиск продолжается по всему B, даже когда элемент уже найден в B. Таким образом, сценарий просматривает список из 370 000 элементы 62000 раз.

Элементы в A и B уникальны (B содержит список уникальных значений от 0 до 700 000, а A содержит уникальное их подмножество), поэтому, как только A [i] будет найден в B, поиск может быть остановлен. Значения также в порядке возрастания, если это что-то значит.

Есть ли способ сделать это быстрее?

Ответы [ 2 ]

7 голосов
/ 14 марта 2019

Это создает новый set(B) для каждого элемента в A. Вместо этого используйте встроенный set.intersection:

C = set(A).intersection(B)
0 голосов
/ 14 марта 2019

Чтобы быть уверенным, что я сделал это как можно быстрее, я бы сделал это:

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

Если вы не хотите потерять свой список B, вы можете просто использовать B вместо B_filter и не объявлять B_filter, поэтому вам не нужно копировать большой список размером 370 КБ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...