Recuerde que las listas no se implementan como listas de enlaces individuales en Python, por lo que esta operación es costosa (como en: es necesario copiar la lista completa). Dependiendo de lo que desee lograr, esto puede ser un problema o no. Solo menciono eso porque este tipo de desestructuración de listas se encuentra a menudo en lenguajes funcionales, donde en realidad es una operación muy barata.
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 headlugar 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 Nonesi no hubiera un elemento principal.
Naturalmente, si está trabajando en una lista, la forma más sencilla sin la sintaxis 3.x es:
lo siento, utilicé el término cola de manera incorrecta. Me refiero a lo que digo en el ejemplo, que es la lista sin el primer elemento
Giacomo d'Antonio
1
@NikolayFominyh Ambos son iguales: ambos toman el elemento principal y construyen una nueva lista que contiene los elementos finales. No hay diferencia de complejidad. Otra clase podría implementar __getitem__/ __setitem__para hacer la operación de cola de manera perezosa, pero la lista incorporada no lo hace.
Gareth Latty
2
En una lista de 800 elementos haciéndolo 1M veces, tengo 2.8s para la solución head, * tail = seq solution y solo 1.8s para head, tail = seq [0], seq [1:] solution. Cortar es aún más rápido para las listas.
Cabu
2
@CMCDragonkai No, la clase de lista principal de Python es una lista de matriz. Esto sería O (n) ya que implica copiar la cola a una nueva lista (con un O (1) obtener para la cabeza).
Gareth Latty
1
Esta agradable sintaxis es otra razón para pasar apython 3.x
Parece que deque (list_instance) tiene complejidad O (N). ¿Me equivoco?
Никита Конин
1
@ НикитаКонин, tienes razón sobre la construcción de deque. Sin embargo, si desea acceder al primer elemento más de una vez, entonces head, tail = l.popleft(), les ~ O (1). head, tail = seq[0], seq[1:]Está encendido).
Nikolay Fominyh
Parece que puedes hacerlo head = l.popleft()y tailes solo un alias para l. Si lcambia tailtambién cambia.
¿Por qué demonios harías esto en lugar de solo 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]
Filipe Pina
1
(1) La pregunta de Op era si es posible hacer esto en una línea (así que no 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].
BobIsNotMyName
Dicho esto, reconozco que esta es una forma mal ofuscada de conseguir la cabeza / cola. Pero pensé que era la mejor respuesta para Python 2 para la pregunta específica de Op.
BobIsNotMyName
1
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]
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:
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, pornext(it, None)
lo que se lo daríaNone
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:]
fuente
__getitem__
/__setitem__
para hacer la operación de cola de manera perezosa, pero la lista incorporada no lo hace.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]
fuente
Sin embargo, para la complejidad de
head,tail
operación O (1) debe utilizardeque
.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.
fuente
head, tail = l.popleft(), l
es ~ O (1).head, tail = seq[0], seq[1:]
Está encendido).head = l.popleft()
ytail
es solo un alias paral
. Sil
cambiatail
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]
fuente
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) Doinghead, tail = lst[0], lst[1:]
deja el código abierto a efectos secundarios (considerarhead, tail = get_list()[0], get_list()[1:]
), y es diferente a la forma de Ophead, 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]
fuente