Suchen des Index eines Elements in einer Liste


3181

Wie erhalte ich bei einer Liste ["foo", "bar", "baz"]und einem Element in der Liste "bar"den Index ( 1) in Python?


6
Kehren Sie zurück: [1] Der niedrigste Index für den Fall, dass es mehrere Instanzen von gibt "bar", [2] Alle Indizes von "bar"?
12gǻňạcểơửṩ

4
a) Ist garantiert, dass sich das Element in der Liste befindet, oder wie sollen wir mit dem Fehlerfall umgehen? (Keine zurückgeben / ValueError erhöhen) b) Sind Listeneinträge garantiert eindeutig und sollten wir den ersten Index einer Übereinstimmung oder alle Indizes zurückgeben?
smci

Zeigen Sie die Antworten mit Numpy-Integration an. Numpy-Arrays sind weitaus effizienter als Python-Listen. Wenn die Liste kurz ist, ist es kein Problem, eine Kopie davon aus einer Python-Liste zu erstellen. Wenn dies nicht der Fall ist, sollten Sie möglicherweise zunächst die Elemente in einem numpy-Array speichern.
Athanassios

Antworten:


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

Referenz: Datenstrukturen> Mehr zu Listen

Vorsichtsmaßnahmen folgen

Beachten Sie, dass , während die ist vielleicht der sauberste Weg , um die Frage zu beantworten , wie gefragt , indexist eine eher schwache Komponente der listAPI, und ich kann das letzte Mal nicht erinnern , habe ich es in Wut. In den Kommentaren wurde ich darauf hingewiesen, dass diese Antwort vollständiger gemacht werden sollte, da sie stark referenziert wird. Einige Vorbehalte list.indexfolgen. Es lohnt sich wahrscheinlich, zunächst einen Blick auf die Dokumentation zu werfen:

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

Gibt einen auf Null basierenden Index in der Liste des ersten Elements zurück, dessen Wert gleich x ist . Löst a aus, ValueErrorwenn es keinen solchen Gegenstand gibt.

Die optionalen Argumente beginnen und end werden wie in der Slice-Notation interpretiert und dienen dazu, die Suche auf eine bestimmte Teilsequenz der Liste zu beschränken. Der zurückgegebene Index wird relativ zum Anfang der vollständigen Sequenz und nicht zum Startargument berechnet.

Lineare Zeitkomplexität in der Listenlänge

Ein indexAufruf überprüft jedes Element der Liste der Reihe nach, bis eine Übereinstimmung gefunden wird. Wenn Ihre Liste lang ist und Sie nicht genau wissen, wo in der Liste sie vorkommt, kann diese Suche zu einem Engpass werden. In diesem Fall sollten Sie eine andere Datenstruktur berücksichtigen. Beachten Sie, dass Sie indexeinen Hinweis geben können, wenn Sie ungefähr wissen, wo Sie die Übereinstimmung finden . Zum Beispiel ist in diesem Snippet l.index(999_999, 999_990, 1_000_000)ungefähr fünf Größenordnungen schneller als geradel.index(999_999) , weil der erstere nur 10 Einträge durchsuchen muss, während der letztere eine Million durchsucht:

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

Gibt nur den Index des zurück ersten Übereinstimmung zu seinem Argument zurück

Ein Aufruf, indexdie Liste der Reihe nach zu durchsuchen, bis eine Übereinstimmung gefunden wird, und dort anzuhalten.Wenn Sie erwarten, dass Indizes mit mehr Übereinstimmungen benötigt werden, sollten Sie ein Listenverständnis oder einen Generatorausdruck verwenden.

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

Die meisten Orte, an denen ich einmal benutzt hätte index ich jetzt ein Listenverständnis oder einen Generatorausdruck, weil sie verallgemeinerbarer sind. Wenn Sie also nach etwas indexgreifen möchten, werfen Sie einen Blick auf diese hervorragenden Python-Funktionen.

Wird ausgelöst, wenn das Element nicht in der Liste vorhanden ist

Ein Aufruf von indexführt zu einem, ValueErrorwenn der Artikel nicht vorhanden ist.

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

Wenn das Element möglicherweise nicht in der Liste vorhanden ist, sollten Sie dies auch tun

  1. Überprüfen Sie es zuerst mit item in my_list (sauberer, lesbarer Ansatz) oder
  2. Schließen Sie den indexAnruf in einen try/exceptBlock ein , der abfängt ValueError(wahrscheinlich schneller, zumindest wenn die zu durchsuchende Liste lang ist und das Element normalerweise vorhanden ist.)

20
index gibt das erste Element zurück, dessen Wert "bar" ist. Wenn "Balken" zweimal in der Liste vorhanden ist, finden Sie nie den Schlüssel für den zweiten "Balken". Siehe Dokumentation: docs.python.org/3/tutorial/datastructures.html
mpoletto

2
Wenn Sie nur nach einem Element (dem ersten) suchen, habe ich festgestellt, dass index()es knapp 90% schneller ist als das Listenverständnis gegenüber Listen von Ganzzahlen.
Slybloty

Welche Datenstruktur sollte verwendet werden, wenn die Liste sehr lang ist?
izhang05

@izhang: Ein zusätzlicher Index, wie ein {element -> list_index} -Diktat, wenn die Elemente hashbar sind und die Position in der Liste von Bedeutung ist.
Alex Coventry

898

Eine Sache, die beim Erlernen von Python wirklich hilfreich ist, ist die Verwendung der interaktiven Hilfefunktion:

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

class list(object)
 ...

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

Dies führt Sie häufig zu der Methode, nach der Sie suchen.


2
bpython ist eine nette benutzerfreundliche Möglichkeit, die Dokumente auf interaktive Weise zu lesen.
Goetzc

@davidavr ja, aber dann hätte der Rest von uns, der es nur googeln möchte, anstatt durch die Hilfedokumente zu scrollen, nicht diese nette, zentrale, geordnete Auswahl an Optionen. :)
Honkaboy

556

In den meisten Antworten wird erläutert, wie ein einzelner Index gefunden wird. Die Methoden geben jedoch nicht mehrere Indizes zurück, wenn das Element mehrmals in der Liste enthalten ist. Verwendung enumerate():

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

Die index()Funktion gibt nur das erste Vorkommen zurück, währendenumerate() alle Vorkommen zurückgegeben werden.

Als Listenverständnis:

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

Hier ist auch eine andere kleine Lösung mit itertools.count()(die so ziemlich dem gleichen Ansatz wie die Aufzählung entspricht):

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

Dies ist für größere Listen effizienter als die Verwendung von 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

Die Aufzählung funktioniert für mich besser als die indexbasierten Methoden, da ich die Indizes von Zeichenfolgen mit 'Startswith' erfassen möchte und mehrere Vorkommen erfassen muss. Oder gibt es eine Möglichkeit, den Index mit 'Startswith' zu verwenden, die ich konnte nicht herausfinden
Tupelo Thistlehead

3
In meinen Händen ist die Aufzählungsversion durchweg etwas schneller. Einige Implementierungsdetails haben sich möglicherweise geändert, seit die obige Messung veröffentlicht wurde.
Alex Coventry

2
Dies wurde bereits seit '11 beantwortet: stackoverflow.com/questions/6294179/…
Cristik


132

index()gibt den ersten Wertindex zurück!

| Index (...)
| L.index (Wert, [Start, [Stopp]]) -> Ganzzahl - Gibt den ersten Wertindex zurück

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

2
Und wenn nicht in der Liste vorhanden?
Peter Mortensen

1
Nicht vorhandenes Element löst ValueError
Nam G VU

1
Diese Antwort würde hier besser passen: stackoverflow.com/questions/6294179/…
Cristik

86

Ein Problem tritt auf, wenn das Element nicht in der Liste enthalten ist. Diese Funktion behandelt das 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


58

Sie müssen eine Bedingung festlegen, um zu überprüfen, ob das gesuchte Element in der Liste enthalten ist

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

1
Dies hilft uns zu vermeiden, versuchen zu fangen!
Devssh

Dies könnte jedoch die Komplexität verdoppeln. Hat jemand nachgesehen?
stefanct

@stefanct Die zeitliche Komplexität ist immer noch linear, durchläuft die Liste jedoch zweimal.
Annäherung

@ApproachingDarknessFish Das habe ich natürlich gemeint. Selbst wenn es pedantisch die gleiche Reihenfolge der Komplexität ist, kann das zweimalige Iterieren in vielen Anwendungsfällen ein schwerwiegender Nachteil sein, daher habe ich es angesprochen. Und wir wissen immer noch nicht die Antwort ...
stefanct

44

Alle hier vorgeschlagenen Funktionen reproduzieren das inhärente Sprachverhalten, verdecken jedoch, was vor sich geht.

[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

Warum eine Funktion mit Ausnahmebehandlung schreiben, wenn die Sprache die Methoden bereitstellt, um selbst das zu tun, was Sie wollen?


9
Die 3. Methode durchläuft die Liste zweimal, oder?
Eric Duminil

Betreff: "Alle hier vorgeschlagenen Funktionen" : Zum Zeitpunkt des Schreibens vielleicht, aber Sie sollten neuere Antworten überprüfen, um festzustellen, ob sie noch wahr sind.
Peter Mortensen

41

Wenn Sie alle Indizes möchten, können Sie NumPy verwenden :

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

Es ist eine klare, lesbare Lösung.


4
Was ist mit Listen von Zeichenfolgen, Listen nicht numerischer Objekte usw.?
Laryx Decidua

1
Diese Antwort sollte besser hier gepostet werden: stackoverflow.com/questions/6294179/…
Cristik

1
Dies ist die beste, die ich gelesen habe. Numpy-Arrays sind weitaus effizienter als Python-Listen. Wenn die Liste kurz ist, ist es kein Problem, eine Kopie davon aus einer Python-Liste zu erstellen. Wenn dies nicht der Fall ist, sollte der Entwickler möglicherweise zunächst in Betracht ziehen, die Elemente in einem Numpy-Array zu speichern.
Athanassios

35

Suchen des Index eines Elements anhand einer Liste, die es in Python enthält

Was ist für eine Liste ["foo", "bar", "baz"]und ein Element in der Liste "bar"der sauberste Weg, um den Index (1) in Python zu erhalten?

Natürlich gibt es die Indexmethode, die den Index des ersten Auftretens zurückgibt:

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

Bei dieser Methode gibt es einige Probleme:

  • Wenn der Wert nicht in der Liste enthalten ist, erhalten Sie eine ValueError
  • Wenn mehr als einer der Werte in der Liste enthalten ist, erhalten Sie nur den Index für den ersten

Keine Werte

Wenn der Wert fehlen könnte, müssen Sie den abfangen ValueError.

Sie können dies mit einer wiederverwendbaren Definition wie der folgenden tun:

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

Und benutze es so:

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

Und der Nachteil davon ist, dass Sie wahrscheinlich prüfen müssen, ob der zurückgegebene Wert isoder is notKeine:

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

Mehr als ein Wert in der Liste

Wenn Sie mehr Vorkommen haben könnten, erhalten Sie keine vollständigen Informationen mit list.index:

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

Sie können die Indizes in ein Listenverständnis auflisten:

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

Wenn Sie keine Vorkommen haben, können Sie dies mit einer booleschen Überprüfung des Ergebnisses überprüfen oder einfach nichts tun, wenn Sie die Ergebnisse durchlaufen:

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

Besseres Datenmunging mit Pandas

Wenn Sie Pandas haben, können Sie diese Informationen einfach mit einem Serienobjekt abrufen:

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

Eine Vergleichsprüfung gibt eine Reihe von Booleschen Werten zurück:

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

Übergeben Sie diese Reihe von Booleschen Werten über die tiefgestellte Notation an die Reihe, und Sie erhalten nur die passenden Mitglieder:

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

Wenn Sie nur die Indizes möchten, gibt das Indexattribut eine Reihe von Ganzzahlen zurück:

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

Und wenn Sie sie in einer Liste oder einem Tupel haben möchten, übergeben Sie sie einfach an den Konstruktor:

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

Ja, Sie könnten auch ein Listenverständnis mit Aufzählung verwenden, aber das ist meiner Meinung nach nicht so elegant - Sie führen in Python Tests auf Gleichheit durch, anstatt den in C geschriebenen eingebauten Code damit umgehen zu lassen:

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

Ist das ein XY-Problem ?

Das XY-Problem fragt eher nach Ihrem Lösungsversuch als nach Ihrem eigentlichen Problem.

Warum muss der Index Ihrer Meinung nach ein Element in einer Liste enthalten?

Wenn Sie den Wert bereits kennen, warum interessiert es Sie, wo er in einer Liste steht?

Wenn der Wert nicht vorhanden ist, ist das Fangen des Werts ValueErrorziemlich ausführlich - und das vermeide ich lieber.

Normalerweise iteriere ich sowieso über die Liste, daher behalte ich normalerweise einen Zeiger auf interessante Informationen und erhalte den Index mit Aufzählung.

Wenn Sie Daten mungieren, sollten Sie wahrscheinlich Pandas verwenden - die weitaus elegantere Tools haben als die reinen Python-Problemumgehungen, die ich gezeigt habe.

Ich erinnere list.indexmich nicht daran , mich selbst gebraucht zu haben. Ich habe jedoch die Python-Standardbibliothek durchgesehen und sehe einige hervorragende Verwendungsmöglichkeiten dafür.

Es gibt viele, viele Verwendungsmöglichkeiten idlelibfür GUI und Textanalyse.

Das keywordModul verwendet es, um Kommentarmarkierungen im Modul zu finden, um die Liste der darin enthaltenen Schlüsselwörter über die Metaprogrammierung automatisch neu zu generieren.

In Lib / mailbox.py scheint es wie eine geordnete Zuordnung verwendet zu werden:

key_list[key_list.index(old)] = new

und

del key_list[key_list.index(key)]

In Lib / http / cookiejar.py scheint verwendet zu werden, um den nächsten Monat zu bekommen:

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

In Lib / tarfile.py ähnlich wie bei distutils, um ein Stück auf einen Gegenstand zu bringen:

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

In Lib / pickletools.py:

numtopop = before.index(markobject)

Was diese Verwendungen gemeinsam zu haben scheinen, ist, dass sie auf Listen mit eingeschränkten Größen zu arbeiten scheinen (wichtig wegen der O (n) -Suchzeit für list.index ) und hauptsächlich beim Parsen verwendet werden (und bei der Benutzeroberfläche im Leerlauf).

Es gibt zwar Anwendungsfälle dafür, diese sind jedoch eher ungewöhnlich. Wenn Sie nach dieser Antwort suchen, fragen Sie sich, ob Sie die Tools, die von der Sprache für Ihren Anwendungsfall bereitgestellt werden, am direktesten verwenden.



21

Abrufen aller Vorkommen und der Position eines oder mehrerer (identischer) Elemente in einer Liste

Mit enumerate (alist) können Sie das erste Element (n) speichern, das der Index der Liste ist, wenn das Element x dem entspricht, wonach Sie suchen.

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

Lassen Sie uns unsere Funktion findindex machen

Diese Funktion verwendet das Element und die Liste als Argumente und gibt die Position des Elements in der Liste zurück, wie wir zuvor gesehen haben.

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

Ausgabe


[1, 3, 5, 7]

Einfach

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

Ausgabe:

0
4

1
Diese Antwort sollte besser hier gepostet werden: stackoverflow.com/questions/6294179/…
Cristik

16

Einfach kann man mitgehen

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

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

16

Andere Option

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

1
Diese Antwort sollte besser hier gepostet werden: stackoverflow.com/questions/6294179/…
Cristik

15

Und jetzt etwas ganz anderes...

... wie die Existenz des Elements zu bestätigen, bevor der Index abgerufen wird. Das Schöne an diesem Ansatz ist, dass die Funktion immer eine Liste von Indizes zurückgibt - auch wenn es sich um eine leere Liste handelt. Es funktioniert auch mit Strings.

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

Beim Einfügen in ein interaktives Python-Fenster:

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

Aktualisieren

Nach einem weiteren Jahr der Heads-Down-Python-Entwicklung ist mir meine ursprüngliche Antwort etwas peinlich. Um den Rekord zu korrigieren, kann man sicherlich den obigen Code verwenden. die viel idiomatischere Weg, um dasselbe Verhalten zu erzielen, wäre jedoch, das Listenverständnis zusammen mit der Funktion enumerate () zu verwenden.

Etwas wie das:

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

Was beim Einfügen in ein interaktives Python-Fenster Folgendes ergibt:

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

Und jetzt, nachdem ich diese Frage und alle Antworten überprüft habe, stelle ich fest, dass dies genau das ist, was FMc in seiner früheren Antwort vorgeschlagen hat . Zu der Zeit, als ich diese Frage ursprünglich beantwortete, tat ich es nicht einmal sehen , dass die Antwort, weil ich es nicht verstand. Ich hoffe, dass mein etwas ausführlicheres Beispiel das Verständnis erleichtert.

Wenn die obige einzelne Codezeile für Sie immer noch keinen Sinn ergibt , empfehle ich Ihnen dringend, Google 'Python-Listenverständnis' zu verwenden, und nehmen Sie sich ein paar Minuten Zeit, um sich mit Ihnen vertraut zu machen. Es ist nur eine der vielen leistungsstarken Funktionen, die es zum Vergnügen machen, mit Python Code zu entwickeln.


12

Eine Variante der Antwort von FMc und user7177 gibt ein Diktat aus, das alle Indizes für jeden Eintrag zurückgeben kann:

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

Sie können dies auch als Einzeiler verwenden, um alle Indizes für einen einzelnen Eintrag abzurufen. Es gibt keine Garantien für die Effizienz, obwohl ich Satz (a) verwendet habe, um die Häufigkeit zu verringern, mit der das Lambda aufgerufen wird.


1
Diese Antwort sollte besser hier gepostet werden: stackoverflow.com/questions/6294179/…
Cristik

10

Diese Lösung ist nicht so leistungsfähig wie andere, aber wenn Sie ein Anfänger sind und nur über forSchleifen Bescheid wissen, ist es immer noch möglich, den ersten Index eines Elements zu finden, während Sie den ValueError vermeiden:

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

9

Index von Element x in Liste L finden:

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

4
Dadurch wird das Array zweimal wiederholt, sodass bei großen Arrays Leistungsprobleme auftreten können.
Cristik

Zustimmen. Wenn die Listen sehr lang sind, würde ich mich für etwas anderes entscheiden. Sollte für kleine bis mittlere Listen jedoch keine große Sache sein.
Ketan

5

Da Python-Listen auf Null basieren, können wir die integrierte Zip-Funktion wie folgt verwenden:

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

Dabei ist "Heuhaufen" die betreffende Liste und "Nadel" das zu suchende Element.

(Hinweis: Hier iterieren wir mit i, um die Indizes zu erhalten. Wenn wir uns jedoch eher auf die Elemente konzentrieren müssen, können wir zu j wechseln.)


3
[i für i, j in Aufzählung (Heuhaufen), wenn j == 'Nadel'] kompakter und lesbarer ist, denke ich.
Giovanni G. PY

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

Dies erklärt, wenn die Zeichenfolge nicht auch in der Liste enthalten ist, wenn sie dann nicht in der Liste enthalten ist location = -1


4

Die Python- index()Methode gibt einen Fehler aus, wenn das Element nicht gefunden wurde. Stattdessen können Sie es der indexOf()Funktion von JavaScript ähnlich machen, die zurückgibt, -1wenn das Element nicht gefunden wurde:

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

5
jedoch JavaScript hat die Philosophie , dass seltsame Ergebnisse sind besser als Fehler, so macht es Sinn zu geben -1 zurück, aber in Python, kann es schwer aufzuspüren Fehler machen, da -1 kehrt ein Element aus dem Ende der Liste.
Sapphire_Brick

3

Darauf gibt es eine funktionalere Antwort.

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

Allgemeinere Form:

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

1
Diese Antwort fühlt sich für Scala/ funktionale Programmier- Enthusiasten zu Hause
y2k-shubham

3

Geben wir lstder Liste, die Sie haben , den Namen . Man kann die Liste lstin eine konvertieren numpy array. Verwenden Sie dann numpy.where , um den Index des ausgewählten Elements in der Liste abzurufen . Im Folgenden wird beschrieben, wie Sie es implementieren.

import numpy as np

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

>>> 1

2

Für diejenigen, die aus einer anderen Sprache wie mir kommen, ist es vielleicht mit einer einfachen Schleife einfacher, sie zu verstehen und zu verwenden:

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

Ich bin dankbar für Also, was genau macht die Aufzählung? . Das hat mir geholfen zu verstehen.


2

Wenn Sie einmal einen Index finden, ist die Verwendung der "Index" -Methode in Ordnung. Wenn Sie Ihre Daten jedoch mehrmals durchsuchen möchten, empfehle ich die Verwendung des Halbierungsmoduls . Beachten Sie, dass die Daten des Halbierungsmoduls sortiert werden müssen. Sie sortieren die Daten also einmal und können dann die Halbierung verwenden. Die Verwendung des Halbierungsmoduls auf meinem Computer ist etwa 20-mal schneller als die Verwendung der Indexmethode.

Hier ist ein Beispiel für Code mit Python 3.8 und höher:

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

Ausgabe:

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

1

Wenn die Leistung von Belang ist:

In zahlreichen Antworten wird erwähnt, dass die eingebaute list.index(item)Methode ein O (n) -Algorithmus ist. Es ist in Ordnung, wenn Sie dies einmal ausführen müssen. Wenn Sie jedoch mehrmals auf die Indizes von Elementen zugreifen müssen, ist es sinnvoller, zuerst ein Wörterbuch (O (n)) von Element-Index-Paaren zu erstellen und dann bei Bedarf auf den Index bei O (1) zuzugreifen es.

Wenn Sie sicher sind, dass die Elemente in Ihrer Liste niemals wiederholt werden, können Sie ganz einfach:

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.

Wenn Sie möglicherweise doppelte Elemente haben und alle ihre Indizes zurückgeben müssen:

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]

1

Wie von @TerryA angegeben, wird in vielen Antworten erläutert, wie ein Index gefunden wird.

more_itertoolsist eine Bibliothek eines Drittanbieters mit Tools zum Auffinden mehrerer Indizes innerhalb einer Iterable.

Gegeben

import more_itertools as mit


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

Code

Finden Sie Indizes für mehrere Beobachtungen:

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

Testen Sie mehrere Elemente:

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

Siehe auch weitere Optionen mit more_itertools.locate. Installieren über > pip install more_itertools.


0

Verwenden Sie das Wörterbuch, wobei Sie zuerst die Liste verarbeiten und dann den Index hinzufügen

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]

-1

Meiner Meinung nach ["foo", "bar", "baz"].index("bar")ist das gut, aber es ist nicht genug! Denn wenn "bar" nicht im Wörterbuch ist, wird es ValueErrorausgelöst. Also können Sie diese Funktion verwenden:

def find_index(arr, name):
    try:
        return arr.index(name)
    except ValueError:
        return -1

if __name__ == '__main__':
    print(find_index(["foo", "bar", "baz"], "bar"))

und das Ergebnis ist:

1

und wenn name nicht bei arr war, gibt die Funktion -1 zurück. Zum Beispiel:

print (find_index (["foo", "bar", "baz"], "fooo"))

-1


1
Verwenden Sie dies nicht, da l = [1, 2]; find_index(l, 3)es zurückkehren -1und zurückkehren l[find_index(l, 3)]würde 2. -1 ist eine schlechte Sache, um zurückzukehren, geben Sie einfach None zurück.
Daniel Stracaboško

-1 ist ein Vertrag, den Sie zurückgeben können, was immer Sie wollen. Versuchen Sie jedoch, in Ihren Programmen weniger None zu verwenden, da None oder Null bei der Kommunikation Ihres Programms mit anderen Programmen wie Android- und PHP-Websites zu Programmunterbrechungen führen kann. Beispielsweise können Sie in JSON null zurückgeben und Ihre Website-Telefonanwendung wird geschlossen oder gibt Fehler 500 zurück (interner Serverfehler).
NaabNuts
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.