Вопрос: Поиск индекса элемента с указанием списка, содержащего его в Python


Список ["foo", "bar", "baz"]и элемент в списке "bar", как я могу получить его индекс (1) в Python?


2167


источник


Ответы:


>>> ["foo", "bar", "baz"].index("bar")
1

Справка: Структуры данных> Подробнее о списках

Предостережения

Обратите внимание, что хотя это, пожалуй, самый чистый способ ответить на вопрос как просили , indexявляется довольно слабым компонентом listAPI, и я не могу вспомнить последний раз, когда я использовал его в гневе. В комментариях было указано, что, поскольку этот ответ в значительной степени упоминается, его следует сделать более полным. Некоторые оговорки о list.indexследовать. Вероятно, стоит сначала взглянуть на документную строку:

>>> print(list.index.__doc__)
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.

Линейная временная сложность в длине списка

indexвызов проверяет каждый элемент списка по порядку, пока не найдет совпадение. Если ваш список длинный, и вы не знаете, где именно находится в списке, этот поиск может стать узким местом. В этом случае вы должны рассмотреть другую структуру данных. Обратите внимание: если вы знаете, где найти матч, вы можете дать indexНамек. Например, в этом фрагменте, l.index(999_999, 999_990, 1_000_000)примерно на пять порядков быстрее, чем прямой l.index(999_999), потому что первый должен искать только 10 записей, в то время как последний ищет миллион:

>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514

Возвращает только индекс первый матч к его аргументу.

Вызов indexпросматривает список, пока не найдет совпадение, и останавливается. Если вам понадобятся индексы большего количества совпадений, вы должны использовать понимание списка или выражение генератора.

>>> [1, 1].index(1)
0
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> next(g)
0
>>> next(g)
2

Большинство мест, где я когда-то пользовался бы index, Теперь я использую выражение для составления списка или генератор, потому что они более обобщаемы. Поэтому, если вы планируете обратиться за index, взгляните на эти превосходные функции python.

Выбрасывает, если элемент отсутствует в списке

Вызов indexприводит к ValueErrorесли элемент отсутствует.

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 2 is not in list

Если элемент может отсутствовать в списке, вы должны либо

  1. сначала проверьте его item in my_list(чистый, читаемый подход) или
  2. обернуть indexпозвонить в try/exceptблок, который улавливает ValueError(вероятно, быстрее, по крайней мере, когда список поиска длинный, и элемент обычно присутствует.)

3220



Одна вещь, которая действительно полезна в изучении Python, заключается в использовании интерактивной функции справки:

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

который часто приведет вас к методу, который вы ищете.


778



Большинство ответов объясняют, как найти один индекс , но их методы не возвращают несколько индексов, если элемент находится в списке несколько раз. использование enumerate():

for i, j in enumerate(['foo', 'bar', 'baz']):
    if j == 'bar':
        print(i)

index()функция возвращает только первое вхождение, тогда как enumerate()возвращает все вхождения.

Как понимание списка:

[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']

Вот еще одно небольшое решение с itertools.count()(это почти такой же подход, как и перечисление):

from itertools import izip as zip, count # izip for maximum efficiency
[i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']

Это более эффективно для больших списков, чем использование enumerate():

$ python -m timeit -s "from itertools import izip as zip, count" "[i for i, j in zip(count(), ['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 174 usec per loop
$ python -m timeit "[i for i, j in enumerate(['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 196 usec per loop

440



Чтобы получить все индексы:

 indexes = [i for i,x in enumerate(xs) if x == 'foo']

119



index() returns the first index of value!

| index(...)
| L.index(value, [start, [stop]]) -> integer -- return first index of value

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

all_indices("foo", ["foo","bar","baz","foo"])

104



A problem will arise if the element is not in the list. This function handles the issue:

# if element is found it returns index of element else returns None

def find_element_in_list(element, list_element):
    try:
        index_element = list_element.index(element)
        return index_element
    except ValueError:
        return None

65



a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']

55



You have to set a condition to check if the element you're searching is in the list

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None

38



All of the proposed functions here reproduce inherent language behavior but obscure what's going on.

[i for i in range(len(mylist)) if mylist[i]==myterm]  # get the indices

[each for each in mylist if each==myterm]             # get the items

mylist.index(myterm) if myterm in mylist else None    # get the first index and fail quietly

Why write a function with exception handling if the language provides the methods to do what you want itself?


34