¿Existe una forma pitónica de descomprimir una lista en el primer elemento y la "cola" en un solo comando?
Por ejemplo:
>> 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]
¿Existe una forma pitónica de descomprimir una lista en el primer elemento y la "cola" en un solo comando?
Por ejemplo:
>> 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]
Respuestas:
En Python 3.x, puede hacer esto muy bien:
>>> head, *tail = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> head
1
>>> tail
[1, 2, 3, 5, 8, 13, 21, 34, 55]
Una nueva característica en 3.x es usar el *
operador al desempacar, para referirse a cualquier valor adicional. Se describe en PEP 3132 - Desembalaje iterable extendido . Esto también tiene la ventaja de trabajar en cualquier iterable, no solo en secuencias.
También es muy legible.
Como se describe en el PEP, si desea hacer el equivalente en 2.x (sin potencialmente hacer una lista temporal), debe hacer esto:
it = iter(iterable)
head, tail = next(it), list(it)
Como se señaló en los comentarios, esto también brinda la oportunidad de obtener un valor predeterminado en head
lugar de lanzar una excepción. Si desea este comportamiento, next()
toma un segundo argumento opcional con un valor predeterminado, por next(it, None)
lo que se lo daría None
si no hubiera un elemento principal.
Naturalmente, si está trabajando en una lista, la forma más sencilla sin la sintaxis 3.x es:
head, tail = seq[0], seq[1:]
__getitem__
/ __setitem__
para hacer la operación de cola de manera perezosa, pero la lista incorporada no lo hace.
python 3.x
Sin embargo, para la complejidad de head,tail
operación O (1) debe utilizar deque
.
Siguiente manera:
from collections import deque
l = deque([1,2,3,4,5,6,7,8,9])
head, tail = l.popleft(), l
Es útil cuando debe recorrer todos los elementos de la lista. Por ejemplo, en la fusión ingenua de 2 particiones en ordenación por fusión.
head, tail = l.popleft(), l
es ~ O (1). head, tail = seq[0], seq[1:]
Está encendido).
head = l.popleft()
y tail
es solo un alias para l
. Si l
cambia tail
también cambia.
Python 2, usando 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]
head, tail = lst[0], lst[1:]
? si OP significa usar un literal, entonces podría dividir la cabeza y la cola manualmentehead, tail = 1, [1, 2, 3, 5, 8, 13, 21, 34, 55]
lst = ...
en la línea anterior). (2) Doing head, tail = lst[0], lst[1:]
deja el código abierto a efectos secundarios (considerar head, tail = get_list()[0], get_list()[1:]
), y es diferente a la forma de Op head, tail = **some_magic applied to** [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
.
Sobre la base de la solución Python 2 de @GarethLatty , la siguiente es una forma de obtener un equivalente de una sola línea sin variables intermedias en Python 2.
t=iter([1, 1, 2, 3, 5, 8, 13, 21, 34, 55]);h,t = [(h,list(t)) for h in t][0]
Si necesita que sea a prueba de excepciones (es decir, que admita una lista vacía), agregue:
t=iter([]);h,t = ([(h,list(t)) for h in t]+[(None,[])])[0]
Si quieres hacerlo sin el punto y coma, usa:
h,t = ([(h,list(t)) for t in [iter([1,2,3,4])] for h in t]+[(None,[])])[0]