tl; dr
Выражение генератора , вероятно , является наиболее производительным и простым решением вашей проблемы:
l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")]
result = next((i for i, v in enumerate(l) if v[0] == 53), None)
Объяснение
Есть несколько ответов, которые обеспечивают простое решение этого вопроса с помощью списков. Хотя эти ответы совершенно верны, они не оптимальны. В зависимости от вашего варианта использования внесение нескольких простых изменений может дать значительные преимущества.
Основная проблема, которую я вижу при использовании понимания списка для этого варианта использования, заключается в том, что будет обработан весь список , хотя вы хотите найти только 1 элемент .
Python предоставляет простую конструкцию, которая здесь идеально подходит. Это называется выражением генератора . Вот пример:
l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")]
next((i for i, v in enumerate(l) if v[0] == 53), None)
Мы можем ожидать, что этот метод будет работать в основном так же, как составление списков в нашем тривиальном примере, но что, если мы работаем с большим набором данных? Вот здесь и проявляется преимущество использования метода генератора. Вместо того, чтобы создавать новый список, мы будем использовать ваш существующий список в качестве нашего итеративного и использовать next()
для получения первого элемента из нашего генератора.
Давайте посмотрим, как эти методы по-разному работают с некоторыми большими наборами данных. Это большие списки, состоящие из 10 000 000 + 1 элементов, с нашей целью в начале (лучший) или конец (худший). Мы можем убедиться, что оба этих списка будут работать одинаково, используя следующее понимание списка:
Составьте список
"Худший случай"
worst_case = ([(False, 'F')] * 10000000) + [(True, 'T')]
print [i for i, v in enumerate(worst_case) if v[0] is True]
"Лучший случай"
best_case = [(True, 'T')] + ([(False, 'F')] * 10000000)
print [i for i, v in enumerate(best_case) if v[0] is True]
Генератор выражений
Вот моя гипотеза для генераторов: мы увидим, что генераторы будут работать значительно лучше в лучшем случае, но точно так же в худшем случае. Это увеличение производительности в основном связано с тем, что генератор вычисляется лениво, то есть он будет вычислять только то, что требуется для получения значения.
Худший случай
Лучший случай
best_case = [(True, 'T')] + ([(False, 'F')] * 10000000)
print next((i for i, v in enumerate(best_case) if v[0] == True), None)
КАКИЕ?! Лучший случай разрушает понимание списка, но я не ожидал, что наш худший случай превзойдет понимание списка в такой степени. Как так? Честно говоря, без дальнейших исследований я мог только предполагать.
Отнеситесь ко всему этому с недоверием, я не проводил здесь какого-либо надежного профилирования, а просто проводил очень простое тестирование. Этого должно быть достаточно, чтобы понять, что выражение генератора более производительно для этого типа поиска по списку.
Обратите внимание, что это все базовый встроенный питон. Нам не нужно ничего импортировать или использовать какие-либо библиотеки.
Впервые я увидел эту технику поиска на курсе Udacity cs212 с Питером Норвигом.