Поиск индекса элемента в списке

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

Вы возвращаетесь: [1] Самый низкий индекс в случае наличия нескольких экземпляров "bar", [2] Все индексы "bar"?

Ṃųỻịgǻňạcểơửṩ 12.05.2018 23:56

a) Гарантировано ли, что элемент находится в списке, или как мы должны обрабатывать случай ошибки? (вернуть None / поднять ValueError) b) Гарантируется ли уникальность записей списка, и должны ли мы возвращать первый индекс совпадения или все индексы?

smci 21.05.2018 09:20

Просмотрите ответы с интеграцией numpy, массивы numpy намного эффективнее списков Python. Если список короткий, это не проблема сделать его копию из списка Python, если нет, то, возможно, вам следует подумать о хранении элементов в массиве numpy в первую очередь.

Athanassios 28.01.2020 15:21
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3 540
3
4 447 083
31
Перейти к ответу Данный вопрос помечен как решенный

Ответы 31

Ответ принят как подходящий

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

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

Предостережения следуют

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

list.index(x[, start[, end]])

Return zero-based index in the list of the first item whose value is equal to x. Raises a ValueError if there is no such item.

The optional arguments start and end are interpreted as in the slice notation and are used to limit the search to a particular subsequence of the list. The returned index is computed relative to the beginning of the full sequence rather than the start argument.

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

Вызов 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 (возможно, быстрее, по крайней мере, когда список для поиска длинный и элемент обычно присутствует).

index возвращает первый элемент, значение которого равно «bar». Если «полоса» существует дважды в списке, вы никогда не найдете ключ для второй «полоски». См. Документацию: docs.python.org/3/tutorial/datastructures.html

mpoletto 30.01.2018 07:51

Если вы ищете только один элемент (первый), я обнаружил, что index() чуть менее чем на 90% быстрее, чем понимание списков по спискам целых чисел.

slybloty 19.09.2019 23:13

Какую структуру данных следует использовать, если список очень длинный?

izhang05 22.02.2020 23:36

@izhang: некоторый вспомогательный индекс, например, {element -> list_index} dict, если элементы являются хешируемыми, и позиция в списке имеет значение.

Alex Coventry 24.02.2020 07:30

sequence1 = sorted (sequence2, key = .sequence3.index) - очень удобная идиома. Вы можете использовать index чаще, если это в вашем репертуаре.

Dvd Avins 24.02.2021 09:42

это правда, @mpoletto ... Что можно сделать в случае наличия нескольких одинаковых значений ???

jvel07 10.03.2021 14:26

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

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

class list(object)
 ...

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

что часто приводит вас к искомому методу.

bpython is a nice user-friendly way to read the docs in an interactive fashion.
goetzc 22.09.2019 21:09

@davidavr да, но тогда у остальных из нас, кто просто хочет погуглить, вместо того, чтобы пролистывать справочную документацию, не было бы этого замечательного центрального ранжированного набора параметров. :)

cydonian 07.04.2020 02:42

index() возвращает индекс значения первый!

| 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"])

А если нет в списке?

Peter Mortensen 04.06.2018 23:16

Несуществующий элемент вызовет ValueError

Nam G VU 13.08.2018 08:29

Этот ответ подошел бы лучше здесь: stackoverflow.com/questions/6294179/…

Cristik 10.02.2019 13:56

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

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

Этот ответ лучше разместить здесь: stackoverflow.com/questions/6294179/…

Cristik 10.02.2019 13:57

Проблема возникнет, если элемента нет в списке. Эта функция решает проблему:

# 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

Все предлагаемые здесь функции воспроизводят внутреннее поведение языка, но скрывают происходящее.

[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

Зачем писать функцию с обработкой исключений, если язык сам предоставляет методы, которые позволяют делать то, что вы хотите?

Третий метод повторяется дважды по списку, верно?

Eric Duminil 05.02.2017 16:59

Re: «Здесь все предлагаемые функции»: Возможно, на момент написания, но вам следует проверить новые ответы, чтобы убедиться, что это все еще правда.

Peter Mortensen 04.06.2018 23:19

Просто ты можешь пойти с

a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
b = ['phone', 'lost']

res = [[x[0] for x in a].index(y) for y in b]

Другой вариант

>>> a = ['red', 'blue', 'green', 'red']
>>> b = 'red'
>>> offset = 0;
>>> indices = list()
>>> for i in range(a.count(b)):
...     indices.append(a.index(b,offset))
...     offset = indices[-1]+1
... 
>>> indices
[0, 3]
>>> 

Этот ответ лучше разместить здесь: stackoverflow.com/questions/6294179/…

Cristik 10.02.2019 13:58

Большинство ответов объясняют, как найти единый индекс, но их методы не возвращают несколько индексов, если элемент находится в списке несколько раз. Используйте 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() (который почти такой же, как и enumerate):

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

Для меня перечисление работает лучше, чем методы, основанные на индексах, поскольку я хочу собрать индексы строк, используя "startwith", и мне нужно собрать несколько вхождений. Или есть способ использовать индекс с "startwith", который я не мог понять

Tupelo Thistlehead 26.10.2017 22:15

В моих руках перечислимая версия стабильно чуть шустрее. Некоторые детали реализации могли измениться после публикации результатов измерения выше.

Alex Coventry 17.11.2017 21:43

Ответ на этот вопрос уже был дан с '11: stackoverflow.com/questions/6294179/…

Cristik 10.02.2019 13:55

такая заставка ответа! спасибо !! .. Я 2 дня пытался получить индекс вложенного словаря, прежде чем понял, что мы можем использовать enumerate

Viv 31.07.2020 19:48

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

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

По этому поводу уже есть еще один вопрос, добавленный в '11: stackoverflow.com/questions/6294179/…

Cristik 10.02.2019 13:56

Вариант ответа от FMc и user7177 даст команду, которая может вернуть все индексы для любой записи:

>>> a = ['foo','bar','baz','bar','any', 'foo', 'much']
>>> l = dict(zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
>>> l['foo']
[0, 5]
>>> l ['much']
[6]
>>> l
{'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}
>>> 

Вы также можете использовать это как один лайнер, чтобы получить все индексы для одной записи. Нет никаких гарантий эффективности, хотя я использовал set (a), чтобы уменьшить количество вызовов лямбда.

Этот ответ лучше разместить здесь: stackoverflow.com/questions/6294179/…

Cristik 10.02.2019 13:59

Вы должны установить условие, чтобы проверить, находится ли искомый элемент в списке.

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

Это помогает нам избежать пробного улова!

devssh 10.09.2018 10:45

Однако это может удвоить сложность. Кто-нибудь проверял?

stefanct 06.09.2019 18:58

@stefanct Сложность времени по-прежнему линейна, но список будет повторяться дважды.

ApproachingDarknessFish 28.01.2020 23:55

@ApproachingDarknessFish Это, очевидно, то, что я имел в виду. Даже если педантично это тот же приказ сложности, повторение дважды может быть серьезным недостатком во многих случаях использования, поэтому я поднял его. И мы до сих пор не знаем ответа ...

stefanct 29.01.2020 04:50

А сейчас нечто соверешнно другое...

... например, подтверждение существования элемента перед получением индекса. В этом подходе хорошо то, что функция всегда возвращает список индексов, даже если это пустой список. Он также работает со струнами.

def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    retval = []
    last = 0
    while val in l[last:]:
            i = l[last:].index(val)
            retval.append(last + i)
            last += i + 1   
    return retval

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')

При вставке в интерактивное окно Python:

Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(the_list, val):
...     """Always returns a list containing the indices of val in the_list"""
...     retval = []
...     last = 0
...     while val in the_list[last:]:
...             i = the_list[last:].index(val)
...             retval.append(last + i)
...             last += i + 1   
...     return retval
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 

Обновлять

Еще через год развития головы вниз питон, я немного смущен мой оригинальный ответ, так, чтобы установить рекорд прямо, можно, конечно, использовать код выше; однако более идиоматическим способом много добиться того же поведения было бы использование понимания списка вместе с функцией enumerate ().

Что-то вроде этого:

def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    return [index for index, value in enumerate(l) if value == val]

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')

Что при вставке в интерактивное окно Python дает:

Python 2.7.14 |Anaconda, Inc.| (default, Dec  7 2017, 11:07:58) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(l, val):
...     """Always returns a list containing the indices of val in the_list"""
...     return [index for index, value in enumerate(l) if value == val]
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 

И теперь, просмотрев этот вопрос и все ответы, я понимаю, что это именно то, что FMc предложил в своем предыдущий ответ. В то время, когда я первоначально ответил на этот вопрос, я даже не ответил на этот вопрос видеть, потому что не понял его. Надеюсь, что мой несколько более подробный пример поможет понять.

Если единственная строка кода выше по-прежнему имеет для вас смысл не, я настоятельно рекомендую вам Google «понимание списка Python» и потратьте несколько минут, чтобы ознакомиться. Это всего лишь одна из многих мощных функций, которые делают использование Python для разработки кода удовольствием.

Это решение не так мощно, как другие, но если вы новичок и знаете только о forloops, все еще можно найти первый индекс элемента, избегая при этом ValueError:

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1

name  = "bar"
list = [["foo", 1], ["bar", 2], ["baz", 3]]
new_list=[]
for item in list:
    new_list.append(item[0])
print(new_list)
try:
    location= new_list.index(name)
except:
    location=-1
print (location)

Это учитывает, что если строка также отсутствует в списке, если ее нет в списке, то location = -1

Все индексы с функцией zip:

get_indexes = lambda x, xs: [i for (y, i) in zip(xs, range(len(xs))) if x == y]

print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
print get_indexes('f', 'xsfhhttytffsafweef')

Этот ответ лучше разместить здесь: stackoverflow.com/questions/6294179/…

Cristik 10.02.2019 13:58

Если вам нужны все индексы, вы можете использовать NumPy:

import numpy as np

array = [1, 2, 1, 3, 4, 5, 1]
item = 1
np_array = np.array(array)
item_index = np.where(np_array==item)
print item_index
# Out: (array([0, 2, 6], dtype=int64),)

Это ясное, читабельное решение.

А как насчет списков строк, списков нечисловых объектов и т. д.?

Laryx Decidua 12.10.2016 17:55

Этот ответ лучше разместить здесь: stackoverflow.com/questions/6294179/…

Cristik 10.02.2019 13:58

Это лучшее, что я читал. массивы numpy намного эффективнее списков Python. Если список короткий, это не проблема сделать его копию из списка Python, если это не так, то, возможно, разработчику в первую очередь следует подумать о хранении элементов в массиве numpy.

Athanassios 28.01.2020 15:23

Получение всех вхождений и положения одного или нескольких (идентичных) элементов в списке

С помощью enumerate (alist) вы можете сохранить первый элемент (n), который является индексом списка, когда элемент x равен тому, что вы ищете.

>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>

Сделаем нашу функцию findindex

Эта функция принимает элемент и список в качестве аргументов и возвращает позицию элемента в списке, как мы видели раньше.

def indexlist(item2find, list_or_string):
  "Returns all indexes of an item in a list or a string"
  return [n for n,item in enumerate(list_or_string) if item==item2find]

print(indexlist("1", "010101010"))

Выход


[1, 3, 5, 7]

Простой

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

Выход:

0
4

Этот ответ лучше разместить здесь: stackoverflow.com/questions/6294179/…

Cristik 10.02.2019 13:59

Поскольку списки Python начинаются с нуля, мы можем использовать встроенную функцию zip следующим образом:

>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]

где «стог сена» - это список, о котором идет речь, а «игла» - это предмет, который нужно искать.

(Примечание: здесь мы повторяем, используя i, чтобы получить индексы, но если нам нужно сосредоточиться на элементах, мы можем переключиться на j.)

[i for i, j in enumerate (haystack) if j == ‘Need’], я думаю, более компактный и читаемый.

Giovanni G. PY 27.12.2017 10:23

Finding the index of an item given a list containing it in Python

For a list ["foo", "bar", "baz"] and an item in the list "bar", what's the cleanest way to get its index (1) in Python?

Ну, конечно, есть метод index, который возвращает индекс первого вхождения:

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

У этого метода есть пара проблем:

  • если значение отсутствует в списке, вы получите ValueError
  • если в списке более одного значения, вы получите индекс только для первого

Нет значений

Если значение могло отсутствовать, вам нужно поймать ValueError.

Вы можете сделать это с помощью такого многоразового определения:

def index(a_list, value):
    try:
        return a_list.index(value)
    except ValueError:
        return None

И используйте это так:

>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1

И обратная сторона этого заключается в том, что у вас, вероятно, будет проверка, если возвращаемое значение is или is not None:

result = index(a_list, value)
if result is not None:
    do_something(result)

Более одного значения в списке

Если у вас может быть больше вхождений, вы нет получите полную информацию с list.index:

>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar')              # nothing at index 3?
1

Вы могли бы перечислить в понимании списка индексы:

>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]

Если у вас нет вхождений, вы можете проверить это с помощью логической проверки результата или просто ничего не делать, если вы перебираете результаты:

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)

Улучшение обмена данными с пандами

Если у вас есть панды, вы можете легко получить эту информацию с помощью объекта Series:

>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0    foo
1    bar
2    baz
3    bar
dtype: object

Проверка сравнения вернет серию логических значений:

>>> series == 'bar'
0    False
1     True
2    False
3     True
dtype: bool

Передайте эту серию логических значений в серию через нотацию нижнего индекса, и вы получите только соответствующие члены:

>>> series[series == 'bar']
1    bar
3    bar
dtype: object

Если вам нужны только индексы, атрибут index возвращает серию целых чисел:

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')

И если вы хотите, чтобы они были в списке или кортеже, просто передайте их конструктору:

>>> list(series[series == 'bar'].index)
[1, 3]

Да, вы также можете использовать понимание списка с enumerate, но, на мой взгляд, это не так элегантно - вы выполняете тесты на равенство в Python, вместо того, чтобы позволять встроенному коду, написанному на C, обрабатывать его:

>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]

Это XY проблема?

The XY problem is asking about your attempted solution rather than your actual problem.

Как вы думаете, зачем вам нужен индекс для элемента в списке?

Если вы уже знаете значение, почему вас волнует, где оно находится в списке?

Если значение отсутствует, поймать ValueError будет довольно многословно - и я предпочитаю этого избегать.

В любом случае я обычно перебираю список, поэтому я обычно сохраняю указатель на любую интересную информацию, получая index с enumerate.

Если вы изменяете данные, вам, вероятно, следует использовать pandas - у которого есть гораздо более элегантные инструменты, чем чистые обходные пути Python, которые я показал.

Я не припоминаю, чтобы мне сам был нужен list.index. Однако я просмотрел стандартную библиотеку Python и увидел несколько отличных применений для нее.

В idlelib его много, много применений для графического интерфейса пользователя и анализа текста.

Модуль keyword использует его для поиска маркеров комментариев в модуле для автоматического восстановления списка ключевых слов в нем посредством метапрограммирования.

В Lib / mailbox.py кажется, что он использует его как упорядоченное сопоставление:

key_list[key_list.index(old)] = new

и

del key_list[key_list.index(key)]

В Lib / http / cookiejar.py, похоже, используется для получения следующего месяца:

mon = MONTHS_LOWER.index(mon.lower())+1

В Lib / tarfile.py аналогично distutils для получения фрагмента до элемента:

members = members[:members.index(tarinfo)]

В Lib / pickletools.py:

numtopop = before.index(markobject)

Что общего у этих способов использования, так это то, что они, похоже, работают со списками ограниченных размеров (что важно из-за времени поиска O (n) для list.index), и они в основном используются при синтаксическом анализе (и пользовательском интерфейсе в случае простоя). .

Хотя для этого есть варианты использования, они довольно редки. Если вы обнаружите, что ищете этот ответ, спросите себя, является ли то, что вы делаете, наиболее прямым использованием инструментов, предоставляемых языком для вашего варианта использования.

Для тех, кто пришел с другого языка, как я, может быть, с помощью простого цикла легче понять и использовать его:

mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
  if item == "bar":
    print(index, item)

Я благодарен Итак, что именно делает enumerate?. Это помогло мне понять.

Метод Python index() выдает ошибку, если элемент не был найден. Поэтому вместо этого вы можете сделать его похожим на функцию indexOf() JavaScript, которая возвращает -1, если элемент не был найден:

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1

однако JavaScript придерживается философии, согласно которой странные результаты лучше ошибок, поэтому имеет смысл возвращать -1, но в Python это может затруднить отслеживание ошибки, поскольку -1 возвращает элемент из конца списка.

Sapphire_Brick 30.10.2019 01:44

На это есть более функциональный ответ.

list(filter(lambda x: x[1]= = "bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"])))

Более общая форма:

def get_index_of(lst, element):
    return list(map(lambda x: x[0],\
       (list(filter(lambda x: x[1]==element, enumerate(lst))))))

Этот ответ подходит энтузиастам Scala / функциональное программирование

y2k-shubham 21.08.2018 08:13

Когда требуется только одно значение в списке, который имеет много совпадений, это занимает много времени.

Caveman 22.06.2020 19:12

Поиск индекса элемента x в списке L:

idx = L.index(x) if (x in L) else -1

Это повторяет массив дважды, что может привести к проблемам с производительностью для больших массивов.

Cristik 10.02.2019 14:00

Соглашаться. Если списки достаточно длинные, я бы выбрал что-нибудь другое. Однако это не должно иметь большого значения для списков малого и среднего размера.

Ketan 25.02.2019 11:13

Если производительность вызывает беспокойство:

В многочисленных ответах упоминается, что встроенный метод метода list.index(item) является алгоритмом O (n). Это нормально, если вам нужно выполнить это один раз. Но если вам нужно получить доступ к индексам элементов несколько раз, имеет смысл сначала создать словарь (O (n)) пар элемент-индекс, а затем обращаться к индексу в O (1) каждый раз, когда вам нужно Это.

Если вы уверены, что элементы в вашем списке никогда не повторяются, вы можете легко:

myList = ["foo", "bar", "baz"]

# Create the dictionary
myDict = dict((e,i) for i,e in enumerate(myList))

# Lookup
myDict["bar"] # Returns 1
# myDict.get("blah") if you don't want an error to be raised if element not found.

Если у вас могут быть повторяющиеся элементы и вам нужно вернуть все их индексы:

from collections import defaultdict as dd
myList = ["foo", "bar", "bar", "baz", "foo"]

# Create the dictionary
myDict = dd(list)
for i,e in enumerate(myList):
    myDict[e].append(i)

# Lookup
myDict["foo"] # Returns [0, 4]

Как указывает @TerryA, во многих ответах обсуждается, как найти индекс один.

more_itertools - это сторонняя библиотека с инструментами для поиска индексов несколько в итерируемом объекте.

Дано

import more_itertools as mit


iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]

Код

Найдите индексы нескольких наблюдений:

list(mit.locate(iterable, lambda x: x == "bar"))
# [1, 5]

Протестируйте несколько предметов:

list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
# [1, 3, 5]

См. Также дополнительные параметры с more_itertools.locate. Устанавливать через > pip install more_itertools.

Давайте дадим имя lst имеющемуся у вас списку. Список lst можно преобразовать в numpy array. Затем используйте numpy.where, чтобы получить индекс выбранного элемента в списке. Вот как вы это реализуете.

import numpy as np

lst = ["foo", "bar", "baz"]  #lst: : 'list' data type
print np.where( np.array(lst) == 'bar')[0][0]

>>> 1

Не работает, если элемент является экземпляром класса

Caveman 22.06.2020 19:11

используя словарь, где сначала обрабатываем список, а затем добавляем к нему индекс

from collections import defaultdict

index_dict = defaultdict(list)    
word_list =  ['foo','bar','baz','bar','any', 'foo', 'much']

for word_index in range(len(word_list)) :
    index_dict[word_list[word_index]].append(word_index)

word_index_to_find = 'foo'       
print(index_dict[word_index_to_find])

# output :  [0, 5]

Если вы собираетесь найти индекс один раз, то можно использовать метод «index». Однако, если вы собираетесь искать свои данные более одного раза, я рекомендую использовать модуль делить пополам. Имейте в виду, что при использовании модуля пополам данные должны быть отсортированы. Таким образом, вы сортируете данные один раз, а затем можете использовать разделение пополам. Использование модуля делить пополам на моем компьютере примерно в 20 раз быстрее, чем использование метода индекса.

Вот пример кода с использованием синтаксиса Python 3.8 и выше:

import bisect
from timeit import timeit

def bisect_search(container, value):
    return (
      index 
      if (index := bisect.bisect_left(container, value)) < len(container) 
      and container[index] == value else -1
    )

data = list(range(1000))
# value to search
value = 666

# times to test
ttt = 1000

t1 = timeit(lambda: data.index(value), number=ttt)
t2 = timeit(lambda: bisect_search(data, value), number=ttt)

print(f"{t1=:.4f}, {t2=:.4f}, diffs {t1/t2=:.2f}")

Выход:

t1=0.0400, t2=0.0020, diffs t1/t2=19.60

Для одного сопоставимого

# Throws ValueError if nothing is found
some_list = ['foo', 'bar', 'baz'].index('baz')
# some_list == 2

Пользовательский предикат

some_list = [item1, item2, item3]

# Throws StopIteration if nothing is found
# *unless* you provide a second parameter to `next`
index_of_value_you_like = next(
    i for i, item in enumerate(some_list)
    if item.matches_your_criteria())

Поиск индекса всех элементов по предикату

index_of_staff_members = [
    i for i, user in enumerate(users)
    if user.is_staff()]

idx = next((i for i, v in enumerate(ls) if v == chk), -1), чтобы получить поведение, подобное str.index (chk).

tejasvi88 10.12.2020 13:42

@ tejasvi88 Решил немного поработать над ответом

Caveman 10.12.2020 14:45

Есть вероятность, что это значение может отсутствовать, поэтому, чтобы избежать этой ValueError, мы можем проверить, действительно ли оно существует в списке.

list =  ["foo", "bar", "baz"]

item_to_find = "foo"

if item_to_find in list:
      index = list.index(item_to_find)
      print("Index of the item is " + str(index))
else:
    print("That word does not exist") 

Другие вопросы по теме