Для списка ["foo", "bar", "baz"]
и элемента в списке " bar "
, как мне получить его индекс (1) в Python?
>>> ["foo", "bar", "baz"].index("bar")
1
Ссылка: Структуры данных > Больше на списках
Обратите внимание, что, хотя это, пожалуй, самый чистый способ ответить на вопрос как было задано , «index» является довольно слабым компонентом API «list», и я не могу вспомнить, когда в последний раз использовал его в гневе. В комментариях мне указывалось, что, поскольку на этот ответ имеются серьезные ссылки, его следует сделать более полным. Ниже приведены некоторые предостережения о list.index
. Вероятно, стоит сначала взглянуть на docstring для этого:
>>> 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
приводит к ValueError
, если элемент отсутствует.
>>> [1, 1].index(2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 2 is not in list
Если элемент может не присутствовать в списке, вы должны либо
item in my_list
(чистый, читаемый подход) илиindex
в блок try / exclude
, который ловит ValueError
(вероятно, быстрее, по крайней мере, когда список для поиска длинный, и элемент обычно присутствует.)Одна вещь, которая действительно полезна при изучении Python, - это использовать интерактивную функцию справки:
>>> help(["foo", "bar", "baz"])
Help on list object:
class list(object)
...
|
| index(...)
| L.index(value, [start, [stop]]) -> integer -- return first index of value
|
что часто приведет вас к методу, который вы ищете.
Большинство ответов объясняют, как найти один индекс , но их методы не возвращают несколько индексов, если элемент находится в списке несколько раз. Используйте 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
Чтобы получить все индексы:
indexes = [i for i,x in enumerate(xs) if x == 'foo']
index ()
возвращает индекс значения first !
| индекс (...) | L.index (значение, [start, [stop]]) - > целое число - вернуть первый индекс значения
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"])
Проблема возникнет, если элемента нет в списке. Эта функция решает проблему:
# 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
Вы должны установить условие, чтобы проверить, находится ли искомый элемент в списке
if 'your_element' in mylist:
print mylist.index('your_element')
else:
print 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
Зачем писать функцию с обработкой исключений, если язык предоставляет методы, чтобы делать то, что вы хотите сами?
Если вы хотите все индексы, то вы можете использовать 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),)
Это четкое, читаемое решение.
Поиск индекса элемента с указанием списка, содержащего его в Python
Для списка
["foo", "bar", "baz"]
и элемента в списке" bar "
, какой самый чистый способ получить свой индекс (1) в Python?
Ну, конечно, есть метод индекса, который возвращает индекс первого вхождения:
>>> 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
И недостатком этого является то, что у вас, вероятно, будет чек на то, является ли возвращаемое значение или
нет `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]
Да, вы могли бы использовать понимание списка и с перечислением, но это, на мой взгляд, не так элегантно - вы проводите тесты на равенство в Python, вместо того, чтобы позволить встроенному коду, написанному на C, обрабатывать его:
>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]
Проблема XY спрашивает о вашем попытке решения, а не о вашей реальной проблеме.
Как вы думаете, зачем индексу данный элемент в списке??
Если вы уже знаете значение, почему вас волнует, где оно находится в списке?
Если значения нет, поймать «ValueError» довольно многословно - и я предпочитаю избегать этого.
В любом случае, я обычно перебираю список, поэтому обычно держу указатель на любую интересную информацию, получая индекс с перечислением.
Если вы собираете данные, вам, вероятно, следует использовать панды, которые имеют гораздо более элегантные инструменты, чем чистые обходные пути 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
), и они в основном используются при синтаксическом анализе (и пользовательском интерфейсе в случай простоя).
Хотя для этого есть варианты использования, они довольно редки. Если вы обнаружите, что ищете этот ответ, спросите себя, является ли то, что вы делаете, наиболее прямым использованием инструментов, предоставляемых языком для вашего варианта использования.
Все индексы с функцией 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')
С помощью 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]
>>>
Эта функция принимает элемент и список в качестве аргументов и возвращает позицию элемента в списке, как мы видели ранее.
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
Еще один вариант
>>> 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]
>>>
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 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]
>>>
После еще одного года разработки питона, I 'Я немного смущен моим первоначальным ответом, так что, чтобы установить рекорд прямо, можно, конечно, использовать приведенный выше код; Однако, гораздо более идиоматическим способом получить такое же поведение было бы использование понимания списка, вместе с перечислением( функция.
Что-то вроде этого:
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 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 для разработки кода.
Вариант ответа от 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), чтобы уменьшить количество раз, когда называется лямбда.
Это решение не так сильно, как другие, но если вы новичок и знаете только о for
loops, все равно можно найти первый индекс элемента, избегая при этом ValueError:
def find_element(p,t):
i = 0
for e in p:
if e == t:
return i
else:
i +=1
return -1
Поиск индекса элемента x в списке L:
idx = L.index(x) if (x in L) else -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