Diese Frage verwirrt mich ein wenig: Möchten Sie rekursiv in allen Ebenen einer mehrdimensionalen Liste nach einem Element suchen oder nur in der obersten Ebene der Liste nach Vorkommen suchen?
Anderson Green
22
Meiner Meinung nach sollte es eine Listenmethode geben, die genau dies tut.
Otocan
Antworten:
545
Sie können ein Listenverständnis verwenden:
indices =[i for i, x in enumerate(my_list)if x =="whatever"]
Verwenden Sie bei älteren Pythons filter () für im Wesentlichen dieselbe Funktionalität.
Gleno
44
Das Listenverständnis zeigte sich in Python bei 2.0, enumeratebei 2.3. Also ja, wenn Ihr Python uralt ist, verwenden Sie filter().
Steven Rumbalski
2
Diese Technik findet nicht alle Vorkommen eines Elements in einem mehrdimensionalen Array. Zum Beispiel print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])gibt []statt [[0, 1], [0, 0], [1, 1]].
Anderson Green
10
@AndersonGreen: Der Begriff "mehrdimensionales Array" schlägt eine Datenstruktur vor, die garantiert eine einheitliche Größe entlang jeder ihrer Achsen aufweist. Es gibt keine solche Datenstruktur in einfachem Python. Es gibt Listen von Listen, aber sie unterscheiden sich stark von "mehrdimensionalen Arrays". Wenn Sie Letzteres möchten, sollten Sie NumPy verwenden, mit dem Sie beispielsweise (a == 1).nonzero()ein NumPy-Array ausführen können a.
Sven Marnach
2
@ MadmanLee Wenn Sie etwas schnelles wollen, verwenden Sie NumPy. Siehe die Antwort von JoshAdel
Georgy
117
Obwohl dies keine direkte Lösung für Listen ist, numpyscheint es wirklich für diese Art von Dingen:
import numpy as np
values = np.array([1,2,3,1,2,4,5,6,3,2,1])
searchval =3
ii = np.where(values == searchval)[0]
kehrt zurück:
ii ==>array([2,8])
Dies kann für Listen (Arrays) mit einer großen Anzahl von Elementen im Vergleich zu einigen anderen Lösungen erheblich schneller sein.
Ich habe festgestellt, dass die [0] am Ende ein Array in einen String konvertiert. Ich bin gespannt, warum Sie sich dafür entschieden haben.
Amelia
5
@amelia [0]wird benötigt, weil whereein Tupel zurückgegeben wird(array([2, 8], dtype=int64),)
Winand
1
Hey @ Winand, ich habe [0] eingegeben, bekomme aber trotzdem beide Teile. Hier ist mein Code: (nrg.local_logs.all_id_resp_address ist eine Liste) "ste =" 199.38.164.165 "value = np.where (nrg.local_logs.all_id_resp_address == ste) [0]" Ich werde mich freuen, wenn Sie es beurteilen können mir was ich falsch gemacht habe
Tomer
2
@Tomer all_id_resp_addresssollte zunächst einmal np.arraynicht sein list.
Winand
1
@Tomer Du versuchen , zu vergleichen listund str, ging man offensichtlich Falsezu np.where. Wenn Sie np.arraymit etw vergleichen . Sie erhalten ein Array von Booleschen Werten. Dann np.wherefindet Positionen aller TrueWerte des Arrays.
Winand
29
Eine Lösung mit list.index:
def indices(lst, element):
result =[]
offset =-1whileTrue:try:
offset = lst.index(element, offset+1)exceptValueError:return result
result.append(offset)
enumerateBei großen Listen ist dies viel schneller als das Listenverständnis. Es ist auch viel langsamer als die numpyLösung, wenn Sie das Array bereits haben, da sonst die Kosten für die Konvertierung den Geschwindigkeitsgewinn überwiegen (getestet auf ganzzahligen Listen mit 100, 1000 und 10000 Elementen).
HINWEIS: Ein Hinweis zur Vorsicht basierend auf dem Kommentar von Chris_Rands: Diese Lösung ist schneller als das Listenverständnis, wenn die Ergebnisse ausreichend spärlich sind, die Liste jedoch viele Instanzen des durchsuchten Elements enthält (mehr als ~ 15% der Liste) Bei einem Test mit einer Liste von 1000 Ganzzahlen ist das Listenverständnis schneller.
Sie sagen, dies ist schneller als eine Listenkomposition. Können Sie Ihre Timings anzeigen, die dies demonstrieren?
Chris_Rands
5
Dies ist eine lange Zeit her, die ich wahrscheinlich timeit.timeitmit zufällig generierten Listen verwendet habe. Das ist jedoch ein wichtiger Punkt, und ich nehme an, das ist vielleicht der Grund, warum Sie fragen. Zu der Zeit ist es mir nicht in den Sinn gekommen, aber die Geschwindigkeitsgewinne sind nur wahr, wenn die Ergebnisse ausreichend spärlich sind. Ich habe gerade mit einer Liste getestet, die das zu suchende Element enthält, und sie ist viel langsamer als das Listenverständnis.
Paulo Almeida
18
Wie wäre es mit:
In[1]: l=[1,2,3,4,3,2,5,6,7]In[2]:[i for i,val in enumerate(l)if val==3]Out[2]:[2,4]
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)
Diese Antwort war für mich am einfachsten in meinen vorhandenen Code zu implementieren.
Ryan Harris
2
Verwenden eines for-loop:
Antworten mit enumerateund ein Listenverständnis sind effizienter und pythonischer. Diese Antwort richtet sich jedoch an Schüler, denen es möglicherweise nicht gestattet ist, einige dieser integrierten Funktionen zu verwenden .
eine leere Liste erstellen, indices
Erstellen Sie die Schleife mit for i in range(len(x)):, die im Wesentlichen eine Liste von Indexpositionen durchläuft[0, 1, 2, 3, ..., len(x)-1]
Fügen Sie in der Schleife any hinzu i, wo x[i]eine Übereinstimmung valuemitindices
def get_indices(x: list, value: int)-> list:
indices = list()for i in range(len(x)):if x[i]== value:
indices.append(i)return indices
n =[1,2,3,-50,-60,0,6,9,-60,-60]print(get_indices(n,-60))>>>[4,8,9]
Die Funktionen get_indiceswerden mit Typhinweisen implementiert . In diesem Fall ist die Liste nein Bündel von ints, daher suchen wir nach value, auch definiert als int.
Verwenden eines while-loopund .index:
Mit .index, Verwendung try-exceptfür die Fehlerbehandlung , weil ein ValueErrortreten auf, wenn valuenicht in der Liste enthalten ist.
def get_indices(x: list, value: int)-> list:
indices = list()
i =0whileTrue:try:# find an occurrence of value and update i to that index
i = x.index(value, i)# add i to the list
indices.append(i)# advance i by 1
i +=1exceptValueErroras e:breakreturn indices
print(get_indices(n,-60))>>>[4,8,9]
Antworten:
Sie können ein Listenverständnis verwenden:
quelle
enumerate
bei 2.3. Also ja, wenn Ihr Python uralt ist, verwenden Siefilter()
.print([i for i, x in enumerate([[1,1],[0,1]]) if x == 1])
gibt[]
statt[[0, 1], [0, 0], [1, 1]]
.(a == 1).nonzero()
ein NumPy-Array ausführen könnena
.Obwohl dies keine direkte Lösung für Listen ist,
numpy
scheint es wirklich für diese Art von Dingen:kehrt zurück:
Dies kann für Listen (Arrays) mit einer großen Anzahl von Elementen im Vergleich zu einigen anderen Lösungen erheblich schneller sein.
quelle
[0]
wird benötigt, weilwhere
ein Tupel zurückgegeben wird(array([2, 8], dtype=int64),)
all_id_resp_address
sollte zunächst einmalnp.array
nicht seinlist
.list
undstr
, ging man offensichtlichFalse
zunp.where
. Wenn Sienp.array
mit etw vergleichen . Sie erhalten ein Array von Booleschen Werten. Dannnp.where
findet Positionen allerTrue
Werte des Arrays.Eine Lösung mit
list.index
:enumerate
Bei großen Listen ist dies viel schneller als das Listenverständnis. Es ist auch viel langsamer als dienumpy
Lösung, wenn Sie das Array bereits haben, da sonst die Kosten für die Konvertierung den Geschwindigkeitsgewinn überwiegen (getestet auf ganzzahligen Listen mit 100, 1000 und 10000 Elementen).HINWEIS: Ein Hinweis zur Vorsicht basierend auf dem Kommentar von Chris_Rands: Diese Lösung ist schneller als das Listenverständnis, wenn die Ergebnisse ausreichend spärlich sind, die Liste jedoch viele Instanzen des durchsuchten Elements enthält (mehr als ~ 15% der Liste) Bei einem Test mit einer Liste von 1000 Ganzzahlen ist das Listenverständnis schneller.
quelle
timeit.timeit
mit zufällig generierten Listen verwendet habe. Das ist jedoch ein wichtiger Punkt, und ich nehme an, das ist vielleicht der Grund, warum Sie fragen. Zu der Zeit ist es mir nicht in den Sinn gekommen, aber die Geschwindigkeitsgewinne sind nur wahr, wenn die Ergebnisse ausreichend spärlich sind. Ich habe gerade mit einer Liste getestet, die das zu suchende Element enthält, und sie ist viel langsamer als das Listenverständnis.Wie wäre es mit:
quelle
quelle
more_itertools.locate
findet Indizes für alle Elemente, die eine Bedingung erfüllen.more_itertools
ist eine Bibliothek eines Drittanbieters> pip install more_itertools
.quelle
conda install
in letzter Zeit sehr instabil geworden ist)Eine weitere Lösung (Entschuldigung, wenn Duplikate) für alle Vorkommen:
quelle
Oder verwenden Sie
range
(Python 3):Für (Python 2):
Und dann (beide Fälle):
Ist wie erwartet.
quelle
Verwenden von filter () in python2.
quelle
Sie können ein Standarddiktat erstellen
quelle
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.
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.
Ausgabe
Einfach
Ausgabe:
quelle
Verwenden eines
for-loop
:enumerate
und ein Listenverständnis sind effizienter und pythonischer. Diese Antwort richtet sich jedoch an Schüler, denen es möglicherweise nicht gestattet ist, einige dieser integrierten Funktionen zu verwenden .indices
for i in range(len(x)):
, die im Wesentlichen eine Liste von Indexpositionen durchläuft[0, 1, 2, 3, ..., len(x)-1]
i
, wox[i]
eine Übereinstimmungvalue
mitindices
x[i]
greift über den Index auf die Liste zuget_indices
werden mit Typhinweisen implementiert . In diesem Fall ist die Listen
ein Bündel vonint
s, daher suchen wir nachvalue
, auch definiert alsint
.Verwenden eines
while-loop
und.index
:.index
, Verwendungtry-except
für die Fehlerbehandlung , weil einValueError
treten auf, wennvalue
nicht in der Liste enthalten ist.quelle
get_indeices
ist etwas schneller (~ 15%) als das normale Listenverständnis. Ich versuche es herauszufinden.Wenn Sie Python 2 verwenden, können Sie damit die gleiche Funktionalität erreichen:
Wo
my_list
ist die Liste, von der Sie die Indizes erhalten möchten, und wovalue
wird der Wert gesucht? Verwendungszweck:quelle
Wenn Sie nach den Positionen aller Elemente zwischen bestimmten Indizes suchen müssen , können Sie diese angeben:
quelle