В качестве нового набора тестов для показа @ EriF89 все еще прав после всех этих лет:
$ python -m timeit -s "l={k:k for k in xrange(5000)}" "[i for i in xrange(10000) if i in l]"
1000 loops, best of 3: 1.84 msec per loop
$ python -m timeit -s "l=[k for k in xrange(5000)]" "[i for i in xrange(10000) if i in l]"
10 loops, best of 3: 573 msec per loop
$ python -m timeit -s "l=tuple([k for k in xrange(5000)])" "[i for i in xrange(10000) if i in l]"
10 loops, best of 3: 587 msec per loop
$ python -m timeit -s "l=set([k for k in xrange(5000)])" "[i for i in xrange(10000) if i in l]"
1000 loops, best of 3: 1.88 msec per loop
Здесь мы также сравниваем a tuple, который, как известно, быстрее lists(и использует меньше памяти) в некоторых случаях использования. В случае справочной таблицы, tupleсработало не лучше.
И то, dictи другое setочень хорошо. Это поднимает интересный момент, связанный с ответом @SilentGhost об уникальности: если у OP есть 10M значений в наборе данных, и неизвестно, есть ли в них дубликаты, тогда было бы целесообразно сохранить набор / указание его элементов параллельно с фактическим набором данных, и проверка на существование в этом наборе / dict. Возможно, что 10M точек данных имеют только 10 уникальных значений, что значительно меньше места для поиска!
Ошибка SilentGhost в отношении dicts на самом деле освещается тем, что можно использовать dict для корреляции дублированных данных (в значениях) в недублированный набор (ключи) и, таким образом, сохранить один объект данных для хранения всех данных, но при этом оставаться быстрым как справочная таблица. Например, ключом dict может быть искомое значение, а значением может быть список индексов в воображаемом списке, где это значение встречается.
Например, если список исходных данных для поиска был l=[1,2,3,1,2,1,4], его можно оптимизировать как для поиска, так и для памяти, заменив его следующим:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> l=[1,2,3,1,2,1,4]
>>> for i, e in enumerate(l):
... d[e].append(i)
>>> d
defaultdict(<class 'list'>, {1: [0, 3, 5], 2: [1, 4], 3: [2], 4: [6]})
С этим диктом можно знать:
- Если значение было в исходном наборе данных (т.е.
2 in dвозвращает True)
- Если значение было в исходном наборе данных (т.е.
d[2]возвращает список индексов , где данные были найдены в первоначальном списке данных: [1, 4])