Самый быстрый способ поиска списка в python
Когда вы делаете что-то вроде "test" in a
, где a
- это список, выполняемый python, выполняет последовательный поиск в списке или создает ли представление хэш-таблицы для оптимизации поиска? В приложении мне это нужно, потому что я буду делать много поисков в списке, так что было бы лучше сделать что-то вроде b = set(a)
, а затем "test" in b
? Также обратите внимание, что список значений, которые у меня будут, не будет иметь повторяющихся данных, и я действительно не забочусь о его заказе; Мне просто нужно проверить наличие значения.
Ответы
Ответ 1
Также обратите внимание, что список значений, которые у меня будут, не будет иметь повторяющихся данных, и я действительно не забочусь о его заказе; Мне просто нужно проверить наличие значения.
Не используйте список, вместо этого используйте set()
. Он имеет именно те свойства, которые вы хотите, включая быстрый тест in
.
Я видел ускорения в 20 раз и выше в местах (в основном тяжелый хруст числа), где один список был изменен для набора.
Ответ 2
"test" in a
со списком a
выполнит линейный поиск. Настройка хеш-таблицы на лету будет намного дороже, чем линейный поиск. "test" in b
, с другой стороны, сделает анимированный O (1) хэш-поиск.
В описанном вами случае не существует причины использовать список по набору.
Ответ 3
Я думаю, что было бы лучше пойти с установленной реализацией. Я знаю, что наборы имеют O (1) время поиска. Я думаю, что списки берут O (n) время поиска. Но даже если списки также относятся к O (1), вы ничего не теряете при переключении на наборы.
Кроме того, в наборах не допускаются повторяющиеся значения. Это также сделает вашу программу более эффективной с точки зрения памяти.
Ответ 4
Список и кортежи, похоже, имеют одно и то же время, а использование "in" медленнее для больших данных:
>>> t = list(range(0, 1000000))
>>> a=time.time();x = [b in t for b in range(100234,101234)];print(time.time()-a)
1.66235494614
>>> t = tuple(range(0, 1000000))
>>> a=time.time();x = [b in t for b in range(100234,101234)];print(time.time()-a)
1.6594209671
Вот гораздо лучшее решение: Самый эффективный способ поиска/поиска в огромном списке (python)
Это супер быстро:
>>> from bisect import bisect_left
>>> t = list(range(0, 1000000))
>>> a=time.time();x = [t[bisect_left(t,b)]==b for b in range(100234,101234)];print(time.time()-a)
0.0054759979248