Wie erhalte ich die Position eines Artikels in einer Liste?

169

Ich iteriere über eine Liste und möchte den Index des Elements ausdrucken, wenn es eine bestimmte Bedingung erfüllt. Wie würde ich das machen?

Beispiel:

testlist = [1,2,3,5,3,1,2,1,6]
for item in testlist:
    if item == 1:
        print position
Sean
quelle

Antworten:

280

Hmmm. Hier gab es eine Antwort mit einem Listenverständnis, die jedoch verschwunden ist.

Hier:

 [i for i,x in enumerate(testlist) if x == 1]

Beispiel:

>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]

Aktualisieren:

Okay, Sie möchten einen Generatorausdruck, wir haben einen Generatorausdruck. Hier ist noch einmal das Listenverständnis in einer for-Schleife:

>>> for i in [i for i,x in enumerate(testlist) if x == 1]:
...     print i
... 
0
5
7

Jetzt bauen wir einen Generator ...

>>> (i for i,x in enumerate(testlist) if x == 1)
<generator object at 0x6b508>
>>> for i in (i for i,x in enumerate(testlist) if x == 1):
...     print i
... 
0
5
7

und geschickt genug, können wir das einer Variablen zuweisen und es von dort aus verwenden ...

>>> gen = (i for i,x in enumerate(testlist) if x == 1)
>>> for i in gen: print i
... 
0
5
7

Und zu denken, ich habe FORTRAN geschrieben.

Charlie Martin
quelle
6
Nach wahrscheinlich 25 Jahren, in denen ich die funktionale Programmierung in Frage gestellt habe, denke ich, dass ich endlich den Hinweis bekomme. Listenverständnis ist da Bombe.
Charlie Martin
15
Ich nehme an, Sie meinen "Einzelbuchstabe" und ehrlich gesagt hätte ein längerer Name in diesem Beispiel keinen weiteren Informationsgehalt.
Charlie Martin
2
Danke für die tolle Antwort. Ich denke, @ nagels Kommentar könnte sich auf die Tatsache beziehen, dass Sie 'i' in zwei verschiedenen Kontexten in einer einzelnen Zeile im Generatorbeispiel verwenden. einer innerhalb des Verständnisses und der andere, um ihn zu durchlaufen. Ich weiß, es hat mich für eine Sekunde abgeworfen.
Brown
1
@CharlieMartin Sie verwenden 'i' für den Index und nicht für das Element gemäß der einen allgemeinen Konvention für Einzelzeichenvariablen. Durch die Benennung des Index 'index' und des Elements 'item' werden Mehrdeutigkeiten beseitigt. Außerdem antworten Sie einem Elternteil, das "Element" und "Position" verwendet hat, und es ist eine gute Art, Teile des ursprünglichen Codes in Ihrer Antwort nicht unnötig umzubenennen.
Mikemaccana
1
Supersyntax: o) Sie können leicht einen Befehlszeilenparameter erhalten. Es gebe eine Reihe von Argumenten : args = ['x', '-p1', 'v1', '-p2', 'v2']. Dann args[[i for i, x in enumerate(args) if x == '-p1'][0] + 1]kehrt der Befehl zurück'v1'
Theodor Keinstein
170

Was ist mit den folgenden?

print testlist.index(element)

Wenn Sie nicht sicher sind, ob das zu suchende Element tatsächlich in der Liste enthalten ist, können Sie eine vorläufige Prüfung hinzufügen, z

if element in testlist:
    print testlist.index(element)

oder

print(testlist.index(element) if element in testlist else None)

oder der "pythonische Weg", den ich nicht so sehr mag, weil Code weniger klar ist, aber manchmal effizienter,

try:
    print testlist.index(element)
except ValueError:
    pass
mmj
quelle
5
Anstatt vor dem Zugriff zu testen, können Sie auch versuchen, nachValueError
kratenko
Ich denke, dass er alle Vorkommen finden will, Sie scheinen nur das erste zu geben.
tfv
@tfv Ich sehe nicht, wie Sie zu einem solchen Schluss kommen können, da die Frage "Artikel" und nicht "Artikel" sagt.
mmj
40

Verwenden Sie Aufzählung:

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position
zdan
quelle
10
for i in xrange(len(testlist)):
  if testlist[i] == 1:
    print i

xrange anstelle des angeforderten Bereichs (siehe Kommentare).

jakber
quelle
Ersetzen Sie range () durch xrange () - range () erstellt eine Liste, xrange () erstellt einen Iterator. xrange () verwendet weniger Speicher und der erste Aufruf ist schneller.
Gnud
2
Ich bin mit großen Listen in Python 2-Programmen einverstanden. Beachten Sie, dass 'range' in Python 3 weiterhin funktioniert (und wie xrange IIRC funktioniert). 'xrange' geht den Weg der Dinosaurier.
Jakber
2
Update: xrangewird in Python 3.x abgelenkt, da das Neue rangedas Alte istxrange
tim-oh
5

Hier ist eine andere Möglichkeit, dies zu tun:

try:
   id = testlist.index('1')
   print testlist[id]
except ValueError:
   print "Not Found"
Phil Rankin
quelle
3
[x for x in range(len(testlist)) if testlist[x]==1]
user1713952
quelle
2

Versuchen Sie Folgendes:

testlist = [1,2,3,5,3,1,2,1,6]    
position=0
for i in testlist:
   if i == 1:
      print(position)
   position=position+1
B Prashantkumar
quelle
1

Wenn Ihre Liste groß genug bekam und man nur erwartet , dass den Wert in einer spärlichen Anzahl von Indizes zu finden, denkt , dass dieser Code könnte viel schneller ausführen , da Sie nicht jeden Wert in der Liste zu iterieren haben.

lookingFor = 1
i = 0
index = 0
try:
  while i < len(testlist):
    index = testlist.index(lookingFor,i)
    i = index + 1
    print index
except ValueError: #testlist.index() cannot find lookingFor
  pass

Wenn Sie erwarten, dass der Wert häufig gefunden wird, sollten Sie wahrscheinlich nur "Index" an eine Liste anhängen und die Liste am Ende ausdrucken, um Zeit pro Iteration zu sparen.


quelle
Ich habe einige Timing-Tests gemacht. Die Listenverständnis-Technik läuft 38% schneller als dieser Code. (Ich habe Ihre Druckanweisung durch einen Aufruf von outputlist.append ersetzt.)
Deestan,
Ich habe auch einige Tests mit Listengrößen von 100000 Zufallswerten zwischen 1 und 100 durchgeführt. Der Code, den ich geschrieben habe, war in einigen Fällen doppelt so schnell. Kein Zeittest ist vergleichbar mit der Anwendung des Posters (sie müssen sich natürlich selbst testen, um sicherzugehen). Ich entschuldige mich, wenn meine Meinung diesem Beitrag abträglich war.
0

Ich denke, dass es nützlich sein könnte, die curselection () -Methode aus der Tkinter-Bibliothek zu verwenden:

from Tkinter import * 
listbox.curselection()

Diese Methode funktioniert mit Tkinter-Listbox-Widgets, daher müssen Sie eines davon anstelle einer Liste erstellen.

Dies gibt eine Position wie folgt zurück:

('0',) (obwohl spätere Versionen von Tkinter möglicherweise stattdessen eine Liste von Ints zurückgeben)

Welches ist für die erste Position und die Nummer ändert sich je nach Position des Artikels.

Weitere Informationen finden Sie auf dieser Seite: http://effbot.org/tkinterbook/listbox.htm

Schöne Grüße.

xXAngelJinXx
quelle
1
Interessante Idee. Da hierfür jedoch die gesamte Tkinter-Bibliothek importiert werden muss, ist dies nicht der effizienteste Weg, um das Problem zu lösen.
Seaotternerd
3
Dies ist ein so ineffizienter und mäanderförmiger Weg, dass ich sagen würde, dass er eine falsche Antwort ist, auch wenn er die Frage etwas anspricht.
Diese Antwort hat nichts mit der Frage zu tun.
Cody Piersall
0

Warum Dinge komplizieren?

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position
Abhishek
quelle
0

Nur um ein vollständiges Beispiel zusammen mit dem zu veranschaulichen, input_listwas hatsearies1 (Beispiel: input_list [0]) , in dem Sie eine Suche nach tun wollen series2(Beispiel: input_list [1]) und erhalten Indizes von series2 wenn es in series1 existiert.

Hinweis: certain conditionWenn die Bedingungen einfach sind, wird der Lambda-Ausdruck verwendet

input_list = [[1,2,3,4,5,6,7],[1,3,7]]
series1 = input_list[0]
series2 = input_list[1]
idx_list = list(map(lambda item: series1.index(item) if item in series1 else None, series2))
print(idx_list)

Ausgabe:

[0, 2, 6]
Ravibeli
quelle
-2
testlist = [1,2,3,5,3,1,2,1,6]
for id, value in enumerate(testlist):
    if id == 1:
        print testlist[id]

Ich denke, dass es genau das ist, was du willst. ;-) 'id' ist immer der Index der Werte in der Liste.

Leonardo
quelle