Python Language
Lista de desestructuración (también conocido como embalaje y desembalaje)
Buscar..
Tarea de destrucción
En las asignaciones, puede dividir un Iterable en valores usando la sintaxis de "desempaquetar":
La destrucción como valores.
a, b = (1, 2)
print(a)
# Prints: 1
print(b)
# Prints: 2
Si intenta desempaquetar más de la longitud del iterable, obtendrá un error:
a, b, c = [1]
# Raises: ValueError: not enough values to unpack (expected 3, got 1)
La destrucción como lista
Puede desempaquetar una lista de longitud desconocida usando la siguiente sintaxis:
head, *tail = [1, 2, 3, 4, 5]
Aquí, extraemos el primer valor como un escalar, y los otros valores como una lista:
print(head)
# Prints: 1
print(tail)
# Prints: [2, 3, 4, 5]
Lo que equivale a:
l = [1, 2, 3, 4, 5]
head = l[0]
tail = l[1:]
También funciona con múltiples elementos o elementos del final de la lista:
a, b, *other, z = [1, 2, 3, 4, 5]
print(a, b, z, other)
# Prints: 1 2 5 [3, 4]
Ignorar valores en las tareas de desestructuración.
Si solo está interesado en un valor dado, puede usar _
para indicar que no está interesado. Nota: esto aún establecerá _
, solo la mayoría de la gente no lo usa como una variable.
a, _ = [1, 2]
print(a)
# Prints: 1
a, _, c = (1, 2, 3)
print(a)
# Prints: 1
print(c)
# Prints: 3
Ignorar listas en tareas de desestructuración.
Finalmente, puede ignorar muchos valores usando la sintaxis *_
en la asignación:
a, *_ = [1, 2, 3, 4, 5]
print(a)
# Prints: 1
lo que no es realmente interesante, ya que podría usar la indexación en la lista. Donde se pone agradable es mantener el primer y último valor en una tarea:
a, *_, b = [1, 2, 3, 4, 5]
print(a, b)
# Prints: 1 5
o extraer varios valores a la vez:
a, _, b, _, c, *_ = [1, 2, 3, 4, 5, 6]
print(a, b, c)
# Prints: 1 3 5
Argumentos de la función de embalaje
En funciones, puede definir una serie de argumentos obligatorios:
def fun1(arg1, arg2, arg3):
return (arg1,arg2,arg3)
lo que hará que la función se pueda llamar solo cuando se den los tres argumentos:
fun1(1, 2, 3)
y puede definir los argumentos como opcionales, utilizando valores predeterminados:
def fun2(arg1='a', arg2='b', arg3='c'):
return (arg1,arg2,arg3)
por lo que puede llamar a la función de muchas maneras diferentes, como:
fun2(1) → (1,b,c)
fun2(1, 2) → (1,2,c)
fun2(arg2=2, arg3=3) → (a,2,3)
...
Pero también puede usar la sintaxis de desestructuración para empacar argumentos, de modo que puede asignar variables usando una list
o un dict
.
Empaquetando una lista de argumentos
Considera que tienes una lista de valores.
l = [1,2,3]
Puede llamar a la función con la lista de valores como un argumento usando la sintaxis *
:
fun1(*l)
# Returns: (1,2,3)
fun1(*['w', 't', 'f'])
# Returns: ('w','t','f')
Pero si no proporciona una lista cuya longitud coincida con el número de argumentos:
fun1(*['oops'])
# Raises: TypeError: fun1() missing 2 required positional arguments: 'arg2' and 'arg3'
Packing argumentos de palabras clave
Ahora, también puede empaquetar argumentos utilizando un diccionario. Puede usar el operador **
para decirle a Python que descomprima el dict
como valores de parámetros:
d = {
'arg1': 1,
'arg2': 2,
'arg3': 3
}
fun1(**d)
# Returns: (1, 2, 3)
cuando la función solo tiene argumentos posicionales (los que no tienen valores predeterminados), necesita que el diccionario contenga todos los parámetros esperados y no tenga un parámetro adicional, o obtendrá un error:
fun1(**{'arg1':1, 'arg2':2})
# Raises: TypeError: fun1() missing 1 required positional argument: 'arg3'
fun1(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun1() got an unexpected keyword argument 'arg4'
Para las funciones que tienen argumentos opcionales, puede empaquetar los argumentos como un diccionario de la misma manera:
fun2(**d)
# Returns: (1, 2, 3)
Pero allí puede omitir valores, ya que serán reemplazados por los valores predeterminados:
fun2(**{'arg2': 2})
# Returns: ('a', 2, 'c')
Y al igual que antes, no puede dar valores adicionales que no sean parámetros existentes:
fun2(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
# Raises: TypeError: fun2() got an unexpected keyword argument 'arg4'
En el uso del mundo real, las funciones pueden tener argumentos tanto posicionales como opcionales, y funciona de la misma manera:
def fun3(arg1, arg2='b', arg3='c')
return (arg1, arg2, arg3)
Puedes llamar a la función con solo un iterable:
fun3(*[1])
# Returns: (1, 'b', 'c')
fun3(*[1,2,3])
# Returns: (1, 2, 3)
o con solo un diccionario:
fun3(**{'arg1':1})
# Returns: (1, 'b', 'c')
fun3(**{'arg1':1, 'arg2':2, 'arg3':3})
# Returns: (1, 2, 3)
o puedes usar ambos en la misma llamada:
fun3(*[1,2], **{'arg3':3})
# Returns: (1,2,3)
Tenga en cuenta que no puede proporcionar varios valores para el mismo argumento:
fun3(*[1,2], **{'arg2':42, 'arg3':3})
# Raises: TypeError: fun3() got multiple values for argument 'arg2'
Desempaquetando argumentos de funciones
Cuando desee crear una función que pueda aceptar cualquier número de argumentos y no imponer la posición o el nombre del argumento en el momento de la "compilación", es posible y a continuación le indicamos cómo:
def fun1(*args, **kwargs):
print(args, kwargs)
Los parámetros *args
y **kwargs
son parámetros especiales que se establecen en una tuple
y un dict
, respectivamente:
fun1(1,2,3)
# Prints: (1, 2, 3) {}
fun1(a=1, b=2, c=3)
# Prints: () {'a': 1, 'b': 2, 'c': 3}
fun1('x', 'y', 'z', a=1, b=2, c=3)
# Prints: ('x', 'y', 'z') {'a': 1, 'b': 2, 'c': 3}
Si observa suficiente código de Python, descubrirá rápidamente que se está utilizando ampliamente al pasar argumentos a otra función. Por ejemplo, si desea extender la clase de cadena:
class MyString(str):
def __init__(self, *args, **kwarg):
print('Constructing MyString')
super(MyString, self).__init__(*args, **kwarg)