python - suma - Operador de estrella*en el lado izquierdo frente al derecho de una declaración de asignación
suma en python (1)
Esta pregunta se deriva de PEP 448
- Generalizaciones de desempaquetado adicionales y está presente en Python 3.5 por lo que yo sé (y no retrocede a 2.x
). Específicamente, en la sección Desventajas , se observa lo siguiente:
Mientras que
*elements, = iterable
hace que loselements
sean unalist
,elements = *iterable
, hace que loselements
sean unatuple
. La razón de esto puede confundir a las personas que no están familiarizadas con la construcción.
Lo que de hecho se mantiene, para iterable = [1, 2, 3, 4]
, el primer caso produce una list
:
>>> *elements, = iterable
>>> elements
[1, 2, 3, 4]
Mientras que para el segundo caso se crea una tuple
:
>>> elements = *iterable,
>>> elements
(1, 2, 3, 4)
Como no estoy familiarizado con el concepto, estoy confundido. ¿Alguien puede explicar este comportamiento? ¿La expresión con estrella actúa de manera diferente dependiendo del lado en el que se encuentra?
La diferencia entre estos dos casos se explica cuando también se tiene en cuenta el PEP inicial para el desempaquetado prolongado: PEP 3132 -- Extended iterable unpacking
.
En el Resumen de ese PEP podemos ver que:
Este PEP propone un cambio a la sintaxis de desempaquetado iterable, que permite especificar un nombre "catch-all" al que se le asignará una lista de todos los elementos no asignados a un nombre "regular".
(énfasis mío)
Entonces en el primer caso , después de ejecutar:
*elements, = iterable
elements
siempre va a ser una list
contiene todos los elementos en el iterable
.
Aunque parece similar en ambos casos, *
en este caso (lado izquierdo) significa: captura todo lo que no está asignado a un nombre y lo asigna a la expresión con estrella. Funciona de manera similar a *args
y **kwargs
do en las definiciones de funciones .
def spam(*args, **kwargs):
""" args and kwargs group positional and keywords respectively """
El segundo caso (lado derecho) es algo diferente . Aquí no tenemos el *
trabajo en una forma de "capturar todo" tanto como lo tenemos funcionando como lo hace normalmente en las llamadas a funciones . Se expande el contenido del iterable al que está conectado. Entonces, la declaración:
elements = *iterable,
se puede ver como:
elements = 1, 2, 3, 4,
que es otra forma de inicializar una tuple
.
Tenga en cuenta que se puede crear una list
usando elements = [*iterable]
simples elements = [*iterable]
que descomprimirá los contenidos de iterable
en []
y dará como resultado asignaciones de los elements = [1, 2, 3, 4]
formulario elements = [1, 2, 3, 4]
.