wake-up-neo.net

Kopf und Schwanz in einer Linie

Gibt es eine pythonische Möglichkeit, eine Liste im ersten Element und den "Schwanz" in einem einzigen Befehl zu entpacken?

Beispielsweise:

>> head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
81

Unter Python 3.x können Sie dies gut tun:

>>> head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]

Eine neue Funktion in 3.x ist die Verwendung des Operators * Beim Entpacken, um zusätzliche Werte zu bezeichnen. Es wird in PEP 3132 - Erweitertes iterierbares Entpacken beschrieben. Dies hat auch den Vorteil, dass nicht nur Sequenzen, sondern beliebige iterable Sequenzen bearbeitet werden.

Es ist auch wirklich lesbar.

Wie im PEP beschrieben, müssen Sie Folgendes tun, wenn Sie das Äquivalent unter 2.x ausführen möchten (ohne möglicherweise eine temporäre Liste zu erstellen):

it = iter(iterable)
head, tail = next(it), list(it)

Wie in den Kommentaren erwähnt, bietet dies auch die Möglichkeit, einen Standardwert für head abzurufen, anstatt eine Ausnahme auszulösen. Wenn Sie dieses Verhalten möchten, nimmt next() ein optionales zweites Argument mit einem Standardwert an, also würde next(it, None) Ihnen None geben, wenn es das gäbe kein Kopfelement.

Wenn Sie an einer Liste arbeiten, ist der einfachste Weg ohne die 3.x-Syntax natürlich:

head, tail = seq[0], seq[1:]
173
Gareth Latty
>>> mylist = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head, tail = mylist[0], mylist[1:]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
35
fraxel

Für O(1) Komplexität von head,tail Operation sollten Sie jedoch deque verwenden.

Folgender Weg:

from collections import deque
l = deque([1,2,3,4,5,6,7,8,9])
head, tail = l.popleft(), l

Dies ist nützlich, wenn Sie alle Elemente der Liste durchlaufen müssen. Zum Beispiel beim naiven Zusammenführen von 2 Partitionen in Mergesort.

8
Nikolay Fominyh

Python 2 mit Lambda

>>> head, tail = (lambda lst: (lst[0], lst[1:]))([1, 1, 2, 3, 5, 8, 13, 21, 34, 55])
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
2
BobIsNotMyName

Aufbauend auf der Python 2-Lösung von @GarethLatty können Sie mit der folgenden Methode ein einziges Zeilenäquivalent ohne Zwischenvariablen in Python= 2) erhalten.

t=iter([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]);h,t = [(h,list(t)) for h in t][0]

Wenn Sie benötigen, dass es ausnahmesicher ist (d. H. Eine leere Liste unterstützt), fügen Sie Folgendes hinzu:

t=iter([]);h,t = ([(h,list(t)) for h in t]+[(None,[])])[0]

Wenn Sie auf das Semikolon verzichten möchten, verwenden Sie:

h,t = ([(h,list(t)) for t in [iter([1,2,3,4])] for h in t]+[(None,[])])[0]
1
ABridgeTooFar