Питання Пошук індексу елемента з зазначенням його списку в Python


Для списку ["foo", "bar", "baz"] і елемент у списку "bar", як отримати свій індекс (1) в Python?


2246
2017-10-07 01:39


походження


Ви повертаєтесь: [1] Найнижчий показник, якщо є кілька екземплярів "bar", [2] Всі показники Росії "bar"? - Mulliganaceous
а) Чи гарантовано, що товар знаходиться в списку, чи як би ми мали справу з справою про помилку? (return No / raise ValueError) b) Чи гарантується, що записи зі списку є унікальними, і чи слід повернути перший індекс матчу або всі індекси? - smci


Відповіді:


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

Довідка: Структури даних> Більше про списки

Застереження слідувати

Зауважте, що, хоча це, мабуть, найчистіший спосіб відповісти на питання як попросили, index є досить слабкою складовою частиною list API, і я не пам'ятаю останнього разу, коли я використовував його в гніві. У коментарі я зазначав, що, оскільки ця відповідь належить до важливих посилань, вона повинна бути більш повною. Деякі застереження про 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 зателефонувати в a try/except блок, який ловить ValueError (швидше за все, швидше, принаймні, коли список для пошуку довгий, а елемент, як правило, присутній).

3308
2017-10-07 01:40



Будьте в курсі, якщо це не в списку, який він кидає, і помилка! - JokerMartini
Індекс повертає перший елемент, значення якого "бар". Якщо "bar" існує двічі у списку, ви ніколи не знайдете ключ для другого "панелі". Див. Документацію: docs.python.org/3/tutorial/datastructures.html - mpoletto
Як це зробити для масиву numpy? - Hendy Irawan
У запитання про те, що елемент знаходиться в списку, передбачено. - Alex Coventry
@smci, дякую, що вказали на це. - Alex Coventry


Одна справа, яка дійсно корисна для вивчення Python, полягає у використанні інтерактивної функції довідки:

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

class list(object)
 ...

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

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


786
2017-10-07 13:19





Більшість відповідей пояснює, як знайти єдиний індекс, але їхні методи не повертають кілька індексів, якщо товар перебуває у списку кілька разів. Використовуйте enumerate():

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

The 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

446
2018-06-19 22:31



Перерахунок ефективніше, ніж для методів на основі індексу, тому що я прагну зібрати індекси рядків, використовуючи "startswith", і мені потрібно збирати кілька випадків. Або є спосіб використання індексу з "startswith", що я не міг зрозуміти - Tupelo Thistlehead
У моїх руках версія переліку постійно трохи швидше. Деякі деталі впровадження, можливо, змінилися з моменту розміщення вищезазначеного виміру. - Alex Coventry
@AlexCoventry Високо залежить від технічних характеристик комп'ютера, але майже п'ять років (wow time flies), я, як правило, погоджуюсь з вами. Особливо з тих пір izip був звільнений з python 3 - TerryA


Щоб отримати всі індекси:

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

123
2018-06-25 15:07





index()повертає перший індекс вартості!

| індекс (...)
   | L.index (значення, [початок, [зупинка]]) -> ціле - повертає перший індекс значення

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

105
2017-08-30 09:40



А якщо не існує в списку? - Peter Mortensen
Ви спробували запустити код, щоб побачити, що він повертає? :-) - HongboZhu


Проблема виникатиме, якщо елемент відсутній у списку. Ця функція обробляє проблему:

# 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

67
2018-04-16 10:19





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

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

57
2017-08-21 12:01



"елемент" - це дуже вводять в оману назву змінної. може бути "індекс"? - johan d.


Ви повинні встановити умову, щоб перевірити, чи знаходиться елемент, який ви шукаєте, у списку

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

39
2018-05-26 04:26





Всі запропоновані функції тут відтворюють внутрішню мовну поведінку, але не розуміють, що відбувається.

[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

Чому пишеться функція із обробкою виключень, якщо мова забезпечує методи, щоб зробити те, що ви хочете себе?


34
2018-05-16 16:45



Третій метод повторюється два рази над списком, чи не так? - Eric Duminil
Re: "Всі запропоновані функції тут": На момент написання, можливо, але ви повинні перевірити новіші відповіді, щоб побачити, чи він все ще вірний. - Peter Mortensen


Якщо вам потрібні всі індекси, то ви можете використовувати 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),)

Це зрозуміло, зрозуміло рішення.


27
2017-11-17 19:05



Як щодо списків рядків, списків нечислових об'єктів тощо? - Laryx Decidua