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

AkiRoss
fuente

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 .

Alex Martelli
fuente
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"))
Valentas
fuente
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.

Uri
fuente
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.

Dominykas Mostauskis
fuente
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.