Expandiendo tuplas en argumentos


411

¿Hay alguna manera de expandir una tupla de Python en una función, como parámetros reales?

Por ejemplo, aquí expand()hace la magia:

some_tuple = (1, "foo", "bar")

def myfun(number, str1, str2):
    return (number * 2, str1 + str2, str2 + str1)

myfun(expand(some_tuple)) # (2, "foobar", "barfoo")

Sé que uno podría definir myfuncomo myfun((a, b, c)), pero por supuesto puede haber código heredado. Gracias

Respuestas:


734

myfun(*some_tuple)hace exactamente lo que pides. El *operador simplemente desempaqueta la tupla (o cualquier iterable) y las pasa como argumentos posicionales a la función. Lea más sobre desempacar argumentos .


8
El operador * simplemente desempaqueta la tupla y las pasa como argumentos posicionales a la función. Ver más aquí: docs.python.org/3/tutorial/…
— john_mc

44
Tenga en cuenta que la misma sintaxis se puede utilizar para listas y tuplas.
— Brendon-ai

Descubrí que puede hacer lo mismo con las listas (de hecho, cualquier iterable, incluidas las cadenas), sin estar seguro de cómo su mutabilidad afecta las cosas. Sería interesante analizarlo.
— wcyn

52

Tenga en cuenta que también puede expandir parte de la lista de argumentos:

myfun(1, *("foo", "bar"))

13
Parece que solo puede hacer esto si la tupla expandida es posterior a los argumentos normalmente proporcionados; al intérprete no le gusta cuando hago esto:some_func(*tuple_of_stuff, another_argument)
— Tom Galvin

66
@Quackmatic Tener la tupla expandida en cualquier ubicación parece funcionar bien en Python 3.5.1
— River

1
@Quackmatic secundando @River, esto funciona bien en Python 3.5.4: def func(a,b,c,d): print(a,b,c,d)conargs = ('fee', 'fi', 'fo'); func(*args, 'fum')
— R. Navega el

15

Eche un vistazo a la sección de tutoriales de Python 4.7.3 y 4.7.4. Habla de pasar tuplas como argumentos.

También consideraría usar parámetros con nombre (y pasar un diccionario) en lugar de usar una tupla y pasar una secuencia. Considero que el uso de argumentos posicionales es una mala práctica cuando las posiciones no son intuitivas o hay múltiples parámetros.


8

Este es el método de programación funcional. Levanta la función de expansión de tupla del azúcar de sintaxis:

apply_tuple = lambda f, t: f(*t)

Ejemplo de uso:

from toolz import * 
from operator import add, eq

apply_tuple = curry(apply_tuple)

thread_last(
    [(1,2), (3,4)],
    (map, apply_tuple(add)),
    list,
    (eq, [3, 7])
)
# Prints 'True'

La redefinición del curryapply_tuple ahorra muchas partialllamadas a largo plazo.


55
Esto no es útil para un principiante. Utiliza módulos de terceros y hace otras cosas confusas ...
— gberger

gberger, lambda f, t: f(*t)no usa módulos de terceros y soy un principiante de Python y esto me ayuda. Este es un enfoque puramente funcional. Si no usa este estilo, esta respuesta no es para usted.
— Dominykas Mostauskis

1
Toolz es de terceros, es lo que quería decir
— gberger

55
No todas las respuestas tienen que ser para principiantes
— Jordania

1
Para el ejemplo que dio, uno puede usar starmap docs.python.org/3.7/library/itertools.html#itertools.starmap
— Bo.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.