Самый быстрый способ проверить, существует ли значение в списке
Какой самый быстрый способ узнать, существует ли значение в списке (список с миллионами значений) и каков его индекс?
Я знаю, что все значения в списке уникальны, как в этом примере.
Первый метод, который я пробую (3.8 секунды в моем реальном коде):.
a = [4,2,3,1,5,6]
if a.count(7) == 1:
b=a.index(7)
"Do something with variable b"
Второй метод, который я пробую (в 2 раза быстрее: 1.9 сек в моем реальном коде):.
a = [4,2,3,1,5,6]
try:
b=a.index(7)
except ValueError:
"Do nothing"
else:
"Do something with variable b"
Предложенные методы от пользователя Stack Overflow (2,74 секунды для моего реального кода):.
a = [4,2,3,1,5,6]
if 7 in a:
a.index(7)
В моем реальном коде первый метод занимает 3,81 сек, а второй - 1,88 сек. Это хорошее улучшение, но..:
Я новичок в Python/скриптинге, есть ли более быстрый способ сделать то же самое и сэкономить больше времени на обработку?
Более конкретная экспликация для моего приложения:
В API Blender я могу получить доступ к списку частиц:
particles = [1, 2, 3, 4, etc.]
Оттуда я могу получить доступ к местоположению частицы:
particles[x].location = [x,y,z]
И для каждой частицы я проверяю, существует ли сосед, выполняя поиск по местоположению каждой частицы следующим образом:
if [x+1,y,z] in particles.location
"Find the identity of this neighbour particle in x:the particle's index
in the array"
particles.index([x+1,y,z])
Самый простой и быстрый способ.
Вы также можете рассмотреть возможность использования
set
, но создание этого набора из вашего списка может занять больше времени, чем сэкономит более быстрое тестирование членства. Единственный способ быть уверенным - это хорошо провести сравнительный анализ. (это также зависит от того, какие операции вам нужны)Как говорят другие, " В " может быть очень медленным для больших списков. Вот некоторые сравнения выступлений на
в
,Set
ипополам
. Обратите внимание на время (в секундах) находится в логарифмической шкале.Код для тестирования:
Вы можете поместить свои элементы в
set
. Поиск по множеству очень эффективен.Попробуйте:
edit В комментарии вы говорите, что хотели бы получить индекс элемента. К сожалению, у множеств нет понятия позиции элемента. Альтернативой может быть предварительная сортировка списка, а затем использование бинарного поиска каждый раз, когда вам нужно найти элемент.
Использование
Я считаю, что это самый быстрый способ узнать, находится ли выбранное значение в массиве.
Это будет хорошая идея, если не't изменить и, таким образом, мы можем сделать дикт() один раз и затем использовать его повторно. Если же изменение, пожалуйста более подробно о том, что вы делаете.
Это звучит как ваше приложение может получить преимущество от использования Блум структуры данных фильтра.
Короче говоря, Блум-фильтр поиска вам могу сказать очень быстро, если значение явно не присутствует в наборе. В противном случае, вы можете делать медленный взгляд-чтобы получить индекс значение, возможно, мог бы быть в списке. Так что если ваше приложение стремится получить то "не нашли" в результате гораздо чаще, чем в "нашли" в результате, вы можете увидеть ускорить путем добавления фильтра Блума.
Подробные сведения Википедию обеспечивает хороший обзор как фильтры Блума работы, и веб-поиска "в библиотеке фильтр на Python Блум", которая обеспечит хотя бы пару полезных реализаций.
Имейте в виду, что
в
оператор проверяет не только равенства (= =
), но и личность (это
),в
логика `списка является примерно равно следующие (Это'ов на самом деле написано в C, а не на Python, хотя, по крайней мере в с CPython):В большинстве случаев эта деталь не имеет никакого значения, но в некоторых обстоятельствах он может оставить на Python новичок удивляет, например, библиотеки numpy.Нань имеет необычное свойство не равных себе:
Чтобы различать эти необычные случаи можно использовать любой () как:
Обратите внимание на
в
логикасписка
любой () будет:Тем не менее, я должен подчеркнуть, что это крайний случай, и для подавляющего большинства случаев " в "оператора" оптимизировать " именно то, что вы хотите, конечно (либо с
список
илимножество
).Или использовать
__содержит__
:Демо:
Это не код, а алгоритм очень быстрый поиск.
Если ваш список и значение, которое вы ищете, все цифры, это довольно просто. Если строки: посмотрите внизу:
Если вы также нуждаетесь в исходное положение, что искать его во втором столбце индекса.
Если ваш список состоит не из чисел, метод все еще работает и будет быстрым, но вы, возможно, потребуется определить функцию, которая может сравнить/строки заказа.
Конечно, это требует инвестиций отсортированный() метод, но если вы будете повторно использовать тот же список для проверки, может быть стоит.
@Уинстон Эверт'ный раствор дает большую скорость для очень больших списков, но в этом сайте StackOverflow ответ указывает, что попробовать:/кроме:/другое: строительство будет замедляться, если за исключением филиала часто достигается. В качестве альтернативы можно воспользоваться
.получить()
метод дикт:`` а = [4,2,3,1,5,6]
индекс = дикт((Г, X) для X, Y в перечислении(а))
показатель B=.вам(7, нет) если б не нет: "и что-то делать с переменной b"и ``
Этот
.вам(ключ, значение по умолчанию) метод-это только для случая, когда вы можете'т гарантия на ключи в dict. Если клавиша * - * присутствует, то она возвращает значение (как бы
словарь[ключ]), но когда это не.получить()
возвращает значение по умолчанию (здесьнет
). Вы должны убедиться в этом случае, что выбранный по умолчанию не будет в "а".Исходный вопрос был:
Таким образом, есть две вещи, чтобы найти:
К этому, я изменил код @xslittlegrass для вычисления индексов во всех случаях, и добавил дополнительный метод.
Результаты
Методы:
Результаты показывают, что Способ 5 самый быстрый.
Интересно попробовать и комплект методы эквивалентного времени.
Тест Код
Этот работал для меня: (понимание списка, один-лайнер)
У меня был
list_to_search_in
со всеми пунктами, и хотел вернуть индексами элементов в list_from_which_to_search`.Это возвращает индексы в хороший список.
Для меня это был 0.030 сек (реальных), 0.026 сек (пользователей) и 0.004 сек (ому).
Код, чтобы проверить, существуют ли в массиве два элемента, произведение которых равно к: