Czy istnieje pythonowy sposób na rozpakowanie listy w pierwszym elemencie i „ogonie” w pojedynczym poleceniu?
Na przykład:
>> 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]
Odpowiedzi:
W Pythonie 3.x możesz to ładnie zrobić:
>>> head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] >>> head 1 >>> tail [1, 2, 3, 5, 8, 13, 21, 34, 55]
Nowością w 3.x jest użycie
*
operatora podczas rozpakowywania, co oznacza wszelkie dodatkowe wartości. Jest to opisane w PEP 3132 - Extended Iterable Unpacking . Ma to również tę zaletę, że pracuje nad dowolnymi iterowalnymi, nie tylko sekwencjami.Jest też bardzo czytelny.
Jak opisano w PEP, jeśli chcesz zrobić odpowiednik w wersji 2.x (bez potencjalnie tworzenia tymczasowej listy), musisz to zrobić:
Jak zauważono w komentarzach, daje to również możliwość uzyskania wartości domyślnej
head
zamiast zgłaszania wyjątku. Jeśli chcesz tego zachowania,next()
pobiera opcjonalny drugi argument z wartością domyślną, więcnext(it, None)
dałby ci,None
gdyby nie było elementu head.Oczywiście, jeśli pracujesz nad listą, najłatwiejszym sposobem bez składni 3.x jest:
head, tail = seq[0], seq[1:]
źródło
__getitem__
/__setitem__
wykonać ogonową operację, ale wbudowana lista nie.python 3.x
>>> 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]
źródło
Jednak ze względu na złożoność
head,tail
operacji O (1) należy użyćdeque
.Podążać drogą:
from collections import deque l = deque([1,2,3,4,5,6,7,8,9]) head, tail = l.popleft(), l
Jest to przydatne, gdy musisz iterować przez wszystkie elementy listy. Na przykład w naiwnym łączeniu 2 partycji w sortowaniu przez scalanie.
źródło
head, tail = l.popleft(), l
jest ~ O (1).head, tail = seq[0], seq[1:]
jest O (n).head = l.popleft()
itail
jest to tylko alias dlal
. Jeślil
changestail
zmiany too.Python 2, używając 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]
źródło
head, tail = lst[0], lst[1:]
? jeśli OP oznacza użycie dosłownego, mógłby ręcznie rozdzielić głowę i ogonhead, tail = 1, [1, 2, 3, 5, 8, 13, 21, 34, 55]
lst = ...
w poprzedniej linii). (2) Wykonaniehead, tail = lst[0], lst[1:]
pozostawia kod otwarty na skutki uboczne (rozważhead, tail = get_list()[0], get_list()[1:]
) i różni się od formy Ophead, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
.Opierając się na rozwiązaniu Python 2 z @GarethLatty , poniżej przedstawiono sposób uzyskania odpowiednika w jednym wierszu bez zmiennych pośrednich w Pythonie 2.
t=iter([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]);h,t = [(h,list(t)) for h in t][0]
Jeśli potrzebujesz, aby był odporny na wyjątki (tj. Obsługujący pustą listę), dodaj:
t=iter([]);h,t = ([(h,list(t)) for h in t]+[(None,[])])[0]
Jeśli chcesz to zrobić bez średnika, użyj:
h,t = ([(h,list(t)) for t in [iter([1,2,3,4])] for h in t]+[(None,[])])[0]
źródło