Вы действительно хотите set
. Наборы быстрее, чем списки, поскольку они могут содержать только уникальные элементы, что позволяет им реализовывать как хэш-таблицы. Хэш-таблицы позволяют проводить тестирование членства (if element in my_set
) в O(1)
времени. Это контрастирует со списками, где единственный способ проверить, если элемент находится в списке, чтобы проверить каждый элемент списка, в свою очередь (в O(n)
времени.)
dict
похож на set
в том, что оба позволяют уникальным только ключи, и оба они реализованы как хэш-таблицы. Они оба допускают тестирование на членство в O(1)
. Разница в том, что set
имеет только ключи, а dict
имеет как ключи, так и значения (что лишние накладные расходы вам не нужны в этом приложении.)
Использование set
, и заменяя вложенный цикл с itertools.chain()
, чтобы сгладить список 2D к 1D списку:
import itertools
seen = set()
for author in itertools.chain(*authors):
seen.add(author)
или короче:
import itertools
seen = set(itertools.chain(*authors))
Edit (спасибо, @jamylak) больше памяти для больших списков:
import itertools
seen = set(itertools.chain.from_iterable(authors))
Пример в списке списков:
>>> a = [[1,2],[1,2],[1,2],[3,4]]
>>> set (itertools.chain(*a))
set([1, 2, 3, 4])
P.S. : Если вместо поиска всех уникальных авторов вы хотите указать кол-во количество раз, когда вы видите каждого автора, используйте collections.Counter
, специальный словарь, оптимизированный для подсчета вещей.
Вот пример подсчета символов в строке:
>>> a = "DEADBEEF CAFEBABE"
>>> import collections
>>> collections.Counter(a)
Counter({'E': 5, 'A': 3, 'B': 3, 'D': 2, 'F': 2, ' ': 1, 'C': 1})
Почему бы вам не задать профиль и/или время, чтобы узнать, какой из них быстрее? –
какой о комплекте? – Aprillion
, что делает его 'set', чтобы сделать его быстрее, чем список для поиска. Он также должен использовать меньше памяти, чем диктофон. Но не верьте мне на слово, попробуйте. –