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

avatar
Eugene M
7 октября 2008 в 01:39
4758163
38
3720

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

Источник
Ṃųỻịgǻňạcểơửṩ
12 мая 2018 в 20:56
6

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

smci
21 мая 2018 в 06:20
4

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

Athanassios
28 января 2020 в 12:21
0

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

Ответы (38)

avatar
Alex Coventry
7 октября 2008 в 01:40
5186
>>> ["foo", "bar", "baz"].index("bar")
1

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

Предупреждения следуйте

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

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

Возвращает отсчитываемый от нуля индекс в списке первого элемента, значение которого равно x . Вызывает ValueError, если такого элемента нет.

Необязательные аргументы start и end интерпретируются как в нотации среза и используются для ограничения поиска определенной подпоследовательностью списка. Возвращенный индекс вычисляется относительно начала полной последовательности, а не начального аргумента.

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

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

mpoletto
30 января 2018 в 04:51
30

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

slybloty
19 сентября 2019 в 20:13
4

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

izhang05
22 февраля 2020 в 20:36
0

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

Alex Coventry
24 февраля 2020 в 04:30
0

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

Dvd Avins
24 февраля 2021 в 06:42
0

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

jvel07
10 марта 2021 в 11:26
0

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

Alex Coventry
14 марта 2021 в 22:05
0

@ jvel07, см. примеры понимания списка / генератора в моем ответе.

avatar
LunaticXXD10
13 января 2022 в 19:49
0

Мой друг, я сделал самый простой код для решения вашего вопроса. Пока вы получали гигантские строки кода, я здесь, чтобы предоставить вам двухстрочный код, который все благодаря помощи функции index() в python.

LIST = ['foo' ,'boo', 'shoo']
print(LIST.index('boo'))

Вывод:

1

Надеюсь, я дал вам лучший и самый простой ответ, который может вам очень помочь.

avatar
sargupta
7 января 2022 в 00:08
0
text = ["foo", "bar", "baz"]
target = "bar"

[index for index, value in enumerate(text) if value == target]

Для небольшого списка элементов это подойдет. Однако, если список содержит большое количество элементов, лучше применить двоичный код поиск со сложностью выполнения O(log n) .

avatar
Franz Kurt
29 декабря 2021 в 18:49
1

Некоторые структуры в Python содержат метод index, который прекрасно работает для решения этого вопроса.

'oi tchau'.index('oi')     # 0
['oi','tchau'].index('oi') # 0
('oi','tchau').index('oi') # 0

Ссылки:

В списках

В кортежах

В строке

avatar
Abdul Niyas P M
28 ноября 2021 в 12:37
1

Pythonic мог бы использовать enumerate, но вы также можете использовать indexOf из модуля operator. Обратите внимание, что при этом будет поднято ValueError, если b не находится в a.

>>> from operator import indexOf
>>>
>>>
>>> help(indexOf)
Help on built-in function indexOf in module _operator:

indexOf(a, b, /)
    Return the first index of b in a.

>>>
>>>
>>> indexOf(("foo", "bar", "baz"), "bar") # with tuple
1
>>> indexOf(["foo", "bar", "baz"], "bar") # with list
1
avatar
MD SHAYON
3 октября 2021 в 14:09
2

Я считаю, что эти два решения лучше, и я попробовал их сам

>>> expences = [2200, 2350, 2600, 2130, 2190]
>>> 2000 in expences
False
>>> expences.index(2200)
0
>>> expences.index(2350)
1
>>> index = expences.index(2350)
>>> expences[index]
2350

>>> try:
...     print(expences.index(2100))
... except ValueError as e:
...     print(e)
... 
2100 is not in list
>>> 


avatar
illuminato
4 мая 2021 в 12:28
0

Простой вариант:

a = ["foo", "bar", "baz"]
[i for i in range(len(a)) if a[i].find("bar") != -1]
avatar
Giacomo Casadei
10 апреля 2021 в 07:48
1

Он просто использует функцию python array.index() и с помощью простого Try / Except возвращает позицию записи, если она найдена в списке, и возвращает -1, если она не найдена в списке (например, в JavaScript с функция indexOf()).

fruits = ['apple', 'banana', 'cherry']

try:
  pos = fruits.index("mango")
except:
  pos = -1

В этом случае «манго» отсутствует в списке fruits, поэтому переменная pos равна -1, если бы я искал «вишню», переменная pos была бы 2.

avatar
Badri Paudel
28 августа 2020 в 09:35
5

Существует вероятность того, что это значение может отсутствовать, поэтому, чтобы избежать этой 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") 
avatar
Caveman
22 июня 2020 в 16:02
4

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

# 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()]
tejasvi88
10 декабря 2020 в 10:42
0

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

Caveman
10 декабря 2020 в 11:45
0

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

avatar
Vlad Bezden
3 апреля 2020 в 16:50
3

Если вы собираетесь найти индекс один раз, то можно использовать метод "index". Однако, если вы собираетесь искать данные более одного раза, я рекомендую использовать модуль bisect. Имейте в виду, что при использовании модуля пополам данные должны быть отсортированы. Таким образом, вы сортируете данные один раз, а затем можете использовать разделение пополам. Использование модуля пополам на моем компьютере примерно в 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
avatar
sahasrara62
18 марта 2019 в 09:32
0

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

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]
avatar
Siddharth Satpathy
14 ноября 2018 в 18:49
2

Давайте дадим имя 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 июня 2020 в 16:11
0

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

avatar
pylang
25 сентября 2018 в 15:47
0

Как указано @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.

avatar
FatihAkici
10 сентября 2018 в 18:51
1

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

В многочисленных ответах упоминается, что встроенный метод метода 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]
avatar
Ketan
25 мая 2018 в 21:56
12

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

idx = L.index(x) if (x in L) else -1
Cristik
10 февраля 2019 в 11:00
5

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

avatar
Ankit Gupta
7 марта 2018 в 19:09
4

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

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))))))
y2k-shubham
21 августа 2018 в 05:13
1

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

Caveman
22 июня 2020 в 16:12
0

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

avatar
Hamed Baatour
4 марта 2018 в 08:39
6

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

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1
Sapphire_Brick
29 октября 2019 в 22:44
7

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

avatar
mpoletto
30 января 2018 в 21:10
2

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

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

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

avatar
Aaron Hall
22 августа 2017 в 03:08
45

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

Для списка ["foo", "bar", "baz"] и элемента в списке "bar", как лучше всего получить его индекс (1) в 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 Нет:

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)

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

Если у вас есть pandas, вы можете легко получить эту информацию с помощью объекта 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?

Проблема XY - это попытка решения, а не реальная проблема.

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

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

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

Я обычно все равно перебираю список, поэтому я обычно сохраняю указатель на любую интересную информацию, получая индекс с помощью 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), и они в основном используются при синтаксическом анализе (и пользовательском интерфейсе в случай простоя).

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

avatar
jihed gasmi
12 августа 2017 в 20:01
4

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

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

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

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

Giovanni G. PY
27 декабря 2017 в 07:23
4

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

avatar
Giovanni G. PY
8 августа 2017 в 05:01
25

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

С помощью 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
Cristik
10 февраля 2019 в 10:59
2

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

Giovanni G. PY
23 июня 2021 в 18:14
0

Хорошо, я сделал это спасибо

avatar
rbrisuda
17 ноября 2015 в 19:05
50

Если вам нужны все индексы, вы можете использовать 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 октября 2016 в 14:55
5

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

Cristik
10 февраля 2019 в 10:58
2

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

Athanassios
28 января 2020 в 12:23
1

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

avatar
Arnaldo P. Figueira Figueira
11 ноября 2015 в 05:16
23

Все индексы с функцией 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')
Cristik
10 февраля 2019 в 10:58
2

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

avatar
Coder123
5 июля 2015 в 13:12
6
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

avatar
dylankb
17 мая 2015 в 03:21
10

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

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1
avatar
MrWonderful
30 декабря 2014 в 21:03
15

А теперь о другом ...

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

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

Обновление

После еще одного года упорной разработки Python я немного смущен своим первоначальным ответом, поэтому, чтобы прояснить ситуацию, можно, конечно, использовать приведенный выше код; однако гораздо более идиоматическим способом добиться того же поведения было бы использование понимания списка вместе с функцией 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 предложил в своем более раннем ответе. В то время, когда я первоначально ответил на этот вопрос, я даже не видел этого ответа, потому что я его не понимал. Надеюсь, что мой несколько более подробный пример поможет понять.

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

avatar
user3670684
26 мая 2014 в 04:26
63

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

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None
devssh
10 сентября 2018 в 07:45
1

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

stefanct
6 сентября 2019 в 15:58
2

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

ApproachingDarknessFish
28 января 2020 в 20:55
1

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

stefanct
29 января 2020 в 01:50
0

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

Matthew Strasiotto
27 июня 2021 в 06:48
0

@stefanct это, вероятно, удваивает сложность, я считаю, что оператор in в списке имеет линейное время выполнения. @ApproachingDarknessFish заявила, что будет повторяться дважды, что отвечает на ваш вопрос, и прав, говоря, что удвоение линейной сложности не является большим делом. Я бы не назвал повторение списка дважды серьезным недостатком во многих случаях использования, поскольку теория сложности говорит нам, что O (n) + O (n) -> O (2 * n) -> O (n), т.е. изменение обычно незначительно.

avatar
bvanlew
28 марта 2014 в 09:11
13

Вариант ответа от 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), чтобы уменьшить количество вызовов лямбда.

Cristik
10 февраля 2019 в 10:59
1

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

avatar
FMc
25 июня 2013 в 15:07
199

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

indexes = [i for i,x in enumerate(xs) if x == 'foo']
Cristik
10 февраля 2019 в 10:56
6

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

avatar
TerryA
19 июня 2013 в 22:31
626

Большинство ответов объясняют, как найти единственный индекс , но их методы не возвращают несколько индексов, если элемент находится в списке несколько раз. Используйте 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
Tupelo Thistlehead
26 октября 2017 в 19:15
1

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

Alex Coventry
17 ноября 2017 в 18:43
5

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

Cristik
10 февраля 2019 в 10:55
4

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

Viv
31 июля 2020 в 16:48
1

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

avatar
Mathitis2Software
29 мая 2013 в 19:17
17

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

>>> 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]
>>> 
Cristik
10 февраля 2019 в 10:58
2

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

avatar
kiriloff
29 мая 2013 в 07:17
19

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

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

res = [[x[0] for x in a].index(y) for y in b]
avatar
Graham Giller
16 мая 2013 в 16:45
47

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

[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
5 февраля 2017 в 13:59
10

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

Peter Mortensen
4 июня 2018 в 20:19
0

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

avatar
tanzil
16 апреля 2013 в 10:19
92

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

# 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
avatar
savinson
21 августа 2012 в 12:01
91
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']
Cristik
10 февраля 2019 в 10:57
2

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

avatar
HongboZhu
30 августа 2011 в 09:40
142

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

| индекс (...)
| L.index (value, [start, [stop]]]) -> integer - вернуть первый индекс значения

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
4 июня 2018 в 20:16
2

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

Nam G VU
13 августа 2018 в 05:29
1

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

Cristik
10 февраля 2019 в 10:56
1

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

avatar
davidavr
7 октября 2008 в 13:19
943

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

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

class list(object)
 ...

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

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

goetzc
22 сентября 2019 в 18:09
5

bpython - удобный и удобный способ интерактивного чтения документации.

cydonian
6 апреля 2020 в 23:42
7

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