Nur Elemente aus einer Einzelelementliste in Python abrufen?

79

Wenn bekannt ist, dass eine Python-Liste immer ein einzelnes Element enthält, gibt es eine andere Möglichkeit, darauf zuzugreifen als:

mylist[0]

Sie können fragen: "Warum sollten Sie wollen?". Neugier allein. Es scheint eine alternative Möglichkeit zu geben, alles in Python zu erledigen .

Pyderman
quelle
5
Es mag Alternativen geben, aber es gibt normalerweise nur einen offensichtlichen Weg, dies zu tun - und in diesem Fall scheinen Sie es bereits gefunden zu haben.
Ekhumoro
Wenn es immer ein einzelnes Element enthält, ist a möglicherweise listnicht der beste Datentyp?
David Zemens
11
@ekhumoro: Ich bin eigentlich ein Teil der Methode zum Entpacken von Sequenzen, da sie die Annahme bestätigt, dass die Sequenz nur ein Element enthält. mylist[0]Erfolgreich, wenn Sie mindestens ein Element haben, sich aber nicht beschweren, wenn Sie tatsächlich 30 Elemente hatten. singleitem, = mylistüberprüft, ob Sie genau ein Element haben, nicht mehr und nicht weniger.
ShadowRanger
1
@ ShadRanger. Bei der Frage geht es explizit um den Zugriff auf das einzige Element in einer Liste, von dem bereits bekannt ist , dass es ein einzelnes Element enthält.
Ekhumoro
6
@ekhumoro: Keine Meinungsverschiedenheit. Ich ziehe es einfach vor, defensiv zu programmieren, damit Verstöße gegen Anforderungen nicht stillschweigend vergehen (sicher, dass es fehlschlägt, aber laut fehlschlägt, was viel einfacher zu identifizieren und zu beheben ist als subtile Fehlverhalten). Wenn ich jedes Mal einen Nickel hätte , wenn sich herausstellen würde, dass ein "bekanntes" Verhalten im Produktionscode absolut falsch ist ... Nun, ich wäre wahrscheinlich nicht reich , aber ich könnte die Familie zu einem wirklich netten bringen Abendessen.
ShadowRanger

Antworten:

118

Sequenz auspacken:

singleitem, = mylist
# Identical in behavior (byte code produced is the same),
# but arguably more readable since a lone trailing comma could be missed:
[singleitem] = mylist

Explizite Verwendung des Iteratorprotokolls:

singleitem = next(iter(mylist))

Destruktiver Pop:

singleitem = mylist.pop()

Negativer Index:

singleitem = mylist[-1]

Wird über eine einzelne Iteration festgelegt for(da die Schleifenvariable beim Beenden einer Schleife mit ihrem letzten Wert verfügbar bleibt):

for singleitem in mylist: break

Viele andere (Kombinieren oder Variieren der oben genannten Teile oder anderweitiges Verlassen auf implizite Iteration), aber Sie haben die Idee.

ShadowRanger
quelle
6
Aufgrund des grassierenden Wahnsinns nicht in die Hauptantwort aufgenommen zu werden: Entpacken des Parameters in eine Funktion mit nur einem Argument (erfolgt als anonymes Lambda, das den Wert für maximal dumm singleitem = (lambda x: x)(*mylist)
zurückgibt
6
Der erste ist insofern einzigartig, als er auch ausgelöst wird, wenn die Liste mehr als ein Element enthält.
Neil G
7
Der erste kann auch als geschrieben werden [singleitem] = mylist.
Carsten S
@NeilG: Leider ist es nicht ganz einzigartig; Die "zügellose Wahnsinns" -Version in den Kommentaren macht das auch (ebenso wie das Entpacken über Listensyntax, obwohl dies tatsächlich identisch mit dem ersten Beispiel in Bezug auf das Verhalten ist). Ich fühle mich jetzt ein bisschen schmutzig.
ShadowRanger
1
@CarstenS: Normalerweise runzele ich die Stirn beim []Entpacken von Sequenzen (macht for [i, x] in enumerate(iterable):mich verrückt), aber ja, beim Entpacken eines einzelnen Werts kann das nachfolgende Komma leicht übersehen werden, und die Verwendung von Klammern ist aus Gründen der Lesbarkeit gerechtfertigt. Ich habe es der Antwort hinzugefügt. Vielen Dank!
ShadowRanger
20

Ich werde hinzufügen, dass die more_itertools Bibliothek ein Tool hat, das ein Element von einem iterablen zurückgibt.

from more_itertools import one


iterable = ["foo"]
one(iterable)
# "foo"

Darüber hinaus more_itertools.onewirft einen Fehler , wenn die iterable leer ist oder mehr als ein Element.

iterable = []
one(iterable)
# ValueError: not enough values to unpack (expected 1, got 0)

iterable = ["foo", "bar"]
one(iterable)
# ValueError: too many values to unpack (expected 1)

more_itertools ist ein Paket von Drittanbietern > pip install more-itertools

Pylang
quelle