Привожу следующий пример. У меня есть два списка, один общий и один с обработанными элементами. Идея, как показывает пример, состоит в том, чтобы исключить элементы, которые уже были обработаны. Проблема в том, что с реальными данными у меня уходит 13 минут! Наверняка его можно как-то оптимизировать. Пожалуйста помоги.
processed = ['a','b','c']
total = [(1, 'a', 'alaksdl'),
(2, 'x', 'asda'),
(3, 'b', 'asda'),
(4, 'c', 'wef'),
(5, 'e', 'asaaa'),
(5, 'j', 'asd')
]
start = time.time()
result = [x for x in total if x[1] not in processed]
end = time.time()
print("Time: ",round(end - start,5), " segundos")
Time: 0.00014 segundos
[(2, 'x', 'asda'), (5, 'e', 'asaaa'), (5, 'j', 'asd')]
result
Просто преобразуйте в промежуточный dict
, удалите элементы processed
и преобразуйте обратно в result
import time
processed = ['a','b','c']
total = [(1, 'a', 'alaksdl'),
(2, 'x', 'asda'),
(3, 'b', 'asda'),
(4, 'c', 'wef'),
(5, 'e', 'asaaa'),
(5, 'j', 'asd')
]
start = time.time()
inter = {x[1]:x for x in total}
for item in processed:
del inter[item]
result = list(inter.values())
end = time.time()
Это должно быть больше похоже на O(n)
Вы можете использовать панд для этого, как показано ниже. Мы будем использовать набор обрабатываемых для метода isin, так как в общем случае поиск значений в наборе намного быстрее, чем в списке. Следующий код занимает несколько секунд для списка из 6 000 000 элементов:
import pandas as pd
df=pd.DataFrame(total)
s=set(processed)
df2=df[-df[1].isin(s)]
res=[tuple(i) for i in df2.values]
>>> print(res)
[(2, 'x', 'asda'), (5, 'e', 'asaaa'), (5, 'j', 'asd')]
s = set(processed)
list(filter(lambda x: x[1] not in s, total))
С 13 минут до 0,28 секунды, всего на 11 десятых секунды больше...