Pytanie Znajdowanie indeksu elementu zawierającego listę zawierającą go w Pythonie


Dla listy ["foo", "bar", "baz"] i element na liście "bar", jak mogę uzyskać jego indeks (1) w Pythonie?


2247
2017-10-07 01:39


pochodzenie


Czy wracasz: [1] Najniższy indeks w przypadku, gdy istnieje wiele instancji "bar", [2] Wszystkie indeksy "bar"? - Mulliganaceous
a) Czy jest zagwarantowane, że pozycja znajduje się na liście, czy też w jaki sposób należy obsłużyć przypadek błędu? (return Brak / podniesienie ValueError) b) Czy pozycje listowe są unikalne i czy powinniśmy zwrócić pierwszy indeks dopasowania lub wszystkie indeksy? - smci


Odpowiedzi:


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

Odniesienie: Struktury danych> Więcej informacji na listach

Zastrzeżenia następujące

Zauważ, że jest to prawdopodobnie najczystszy sposób na odpowiedź na pytanie na pytanie, index jest raczej słabym komponentem list API i nie pamiętam, kiedy ostatnio używałam go w gniewie. W komentarzach wskazano mi, że ponieważ ta odpowiedź jest silnie powiązana, powinna być bardziej kompletna. Niektóre zastrzeżenia dotyczą list.index śledzić. Najprawdopodobniej warto najpierw przyjrzeć się docstringowi:

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

Liniowy czas złożoności w długości listy

Na index sprawdza wszystkie elementy listy w kolejności, dopóki nie znajdzie dopasowania. Jeśli twoja lista jest długa i nie wiesz z grubsza, gdzie na liście występuje, to wyszukiwanie może stać się wąskim gardłem. W takim przypadku należy wziąć pod uwagę inną strukturę danych. Zauważ, że jeśli wiesz z grubsza, gdzie znaleźć dopasowanie, możesz dać index Wskazówka. Na przykład w tym fragmencie l.index(999_999, 999_990, 1_000_000) jest mniej więcej pięć rzędów wielkości szybsza od prostej l.index(999_999), ponieważ ten pierwszy musi tylko przeszukać 10 pozycji, podczas gdy drugi szuka miliona:

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

Zwraca tylko indeks pliku pierwszy mecz do jego argumentu

Połączenie z index przeszukuje listę w kolejności, dopóki nie znajdzie dopasowania, i zatrzymuje się tam. Jeśli spodziewasz się, że potrzebujesz wskaźników więcej dopasowań, powinieneś użyć zrozumienia list lub wyrażenia generatora.

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

W większości miejsc, w których kiedyś bym skorzystał indexUżywam teraz wyrażeń listowych lub wyrażeń generujących, ponieważ są one bardziej uogólnione. Jeśli więc zastanawiasz się nad rozwiązaniem index, spójrz na te doskonałe funkcje Pythona.

Zgłasza, jeśli element nie występuje na liście

Połączenie z index wyniki w ValueError jeśli przedmiot nie jest obecny.

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

Jeśli element może nie być obecny na liście, powinieneś

  1. Najpierw sprawdź to item in my_list (czyste, czytelne podejście), lub
  2. Owiń index zadzwoń do a try/except blok, który łapie ValueError (prawdopodobnie szybciej, przynajmniej gdy lista do wyszukania jest długa, a przedmiot zwykle jest obecny).

3308
2017-10-07 01:40



bądź świadomy, jeśli nie ma go na liście, którą rzuca i popełnia błąd! - JokerMartini
index zwraca pierwszy element, którego wartością jest "bar". Jeśli "pasek" istnieje dwa razy na liście, nigdy nie znajdziesz klucza do drugiego "paska". Zobacz dokumentację: docs.python.org/3/tutorial/datastructures.html - mpoletto
Jak to zrobić dla numpy array? - Hendy Irawan
Jest to określone w pytaniu, że przedmiot znajduje się na liście. - Alex Coventry
@smci, dzięki za wskazanie tego. - Alex Coventry


Jedną z rzeczy, która jest naprawdę pomocna w uczeniu się Pythona, jest skorzystanie z interaktywnej funkcji pomocy:

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

class list(object)
 ...

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

co często doprowadzi cię do metody, której szukasz.


786
2017-10-07 13:19





Większość odpowiedzi wyjaśnia, jak znaleźć jeden indeks, ale ich metody nie zwracają wielu indeksów, jeśli element jest na liście wiele razy. Posługiwać się enumerate():

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

The index() funkcja zwraca tylko pierwsze wystąpienie, natomiast enumerate() zwraca wszystkie wystąpienia.

W ramach rozumienia listy:

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

Oto także inne małe rozwiązanie z itertools.count() (co jest prawie takie samo podejście jak wyliczenie):

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

Jest to bardziej skuteczne w przypadku większych list niż przy użyciu 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



Wyliczenie działa lepiej niż metody oparte na indeksach, ponieważ staram się zebrać indeksy łańcuchów przy użyciu "startswith", i muszę zebrać wiele wystąpień.A może istnieje sposób, aby użyć indeksu z "startswith", że I nie mogłem wymyślić - Tupelo Thistlehead
W moich rękach wersja wyliczeniowa jest konsekwentnie nieco szybsza. Niektóre szczegóły implementacji mogły ulec zmianie od momentu opublikowania powyższego pomiaru. - Alex Coventry
@AlexCoventry Bardzo zależy od specyfikacji komputera, ale prawie pięć lat później (wow muchy), chciałbym się z tobą zgodzić. Zwłaszcza od kiedy izip został nadmiarowy w pythonie 3 - TerryA


Aby uzyskać wszystkie indeksy:

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

123
2018-06-25 15:07





index()zwraca wartość pierwszy indeks wartości!

| indeks(...)
   | L.index (value, [start, [stop]]) -> integer - zwraca pierwszy indeks wartości

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



A jeśli nie ma na liście? - Peter Mortensen
czy próbowałeś uruchomić kod, aby zobaczyć, co zwraca? :-) - HongboZhu


Pojawi się problem, jeśli element nie znajduje się na liście. Ta funkcja obsługuje problem:

# 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



"item" jest bardzo mylącą nazwą zmiennej. może "indeks"? - johan d.