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.