Link Search Menu Expand Document

Unpacking en Python

El unpacking en Python nos permite asignar una lista a múltiples variables en una única línea de código.

a, b, c = [1, 2, 3]
print(a) # 1
print(b) # 2
print(c) # 3

También es posible hacerlo con otros iterables como las tuplas.

a, b, c = (1, 2, 3)
print(a) # 1
print(b) # 2
print(c) # 3

Y como es de esperar, el número de variables debe coincidir con la longitud. Obtenemos not enough values to unpack si proporcionamos menos.

a, b, c = (1, 2)
# ValueError: not enough values to unpack (expected 3, got 2)

Y too many values to unpack si proporcionamos de más.

a, b = (1, 2, 3, 4)
# ValueError: too many values to unpack (expected 2)

Se pueden dar casos curiosos como el siguiente, ya que en realidad funciona con cualquier iterable.

a, b, c = "123"
print(a) # 1
print(b) # 2
print(c) # 3

De hecho funciona también con diccionarios, siendo la key lo usado por defecto.

a, b, c = {'uno': 1, 'dos':2, 'tres': 3}
print(a) # uno
print(b) # dos
print(c) # tres

Aunque también podemos usar los values.

a, b, c = {'uno': 1, 'dos':2, 'tres': 3}.values()
print(a) # 1
print(b) # 2
print(c) # 3

Dado que range devuelve un iterador, también lo podemos usar.

a, b, c = range(3)
print(a) # 0
print(b) # 1
print(c) # 2

Operador de Unpacking

Relacionado con el unpacking existe el operador *, que nos permite realizar asignaciones cuando el número de elementos es distinto. Tanto de esta manera.

*a, b = (1, 2, 3)
print(a) # [1, 2]
print(b) # 3

Como de esta otra.

a, *b = (1, 2, 3)
print(a) # 1
print(b) # [2, 3]

Podemos usarlo para unir listas. Aunque es importante notar que esto se puede hacer de otras formas como usando + o .extend().

a = [1, 2]
b = [3, 4]
c = [*a, *b]

print(c)
# [1, 2, 3, 4]

También tenemos el operador definido para diccionarios, usando **.

a = {"uno": 1, "dos": 2}
b = {"tres": 3, "cuatro": 4}

c = {**a, **b}

print(c)
# {'uno': 1, 'dos': 2, 'tres': 3, 'cuatro': 4}

Ten cuidado si tienes keys duplicados, ya que el segundo sobrescribirá al primero.

a = {"uno": 1, "dos": 2}
b = {"uno": 0, "dos": 0}

c = {**a, **b}

print(c)
# {'uno': 0, 'dos': 0}

Y por último también podemos hacer cosas interesantes con bucles for.

for primero, *resto in [(1, 2, 3), (4, 5, 6, 7)]:
    print("Primero:", primero)
    print("Resto:", resto)
    
# Primero: 1
# Resto: [2, 3]
# Primero: 4
# Resto: [5, 6, 7]

Unpacking para Swapping

La principal aplicación práctica del unpacking es para intercambiar o hacer swap de variables en una única línea de código. Aunque pueda parecer algo sencillo, no todos los lenguajes permiten esto.

a, b = (1, 2)
print(a, b)
# 1 2

a, b = b, a
print(a, b)
# 2 1

Unpacking en Funciones

Por último, aunque lo vemos más en detalle en args y kwargs, el unpacking nos permite pasar un número de argumentos variables a una función.

def funcion(a, *args, **kwargs):
    print(f"args={a} args={args} kwargs={kwargs}")

funcion(1)
# args=1 args=() kwargs={}

funcion(1, 2)
# args=1 args=(2,) kwargs={}

funcion(1, 2, 3, cuatro=4, cinco=5)
# args=1 args=(2, 3) kwargs={'cuatro': 4, 'cinco': 5}