Extension des tuples en arguments

411

Existe-t-il un moyen d'étendre un tuple Python en fonction - en tant que paramètres réels?

Par exemple, voici expand()la magie:

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

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

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

Je sais que l'on pourrait définir myfuncomme myfun((a, b, c)), mais bien sûr, il peut y avoir un code hérité. Merci

AkiRoss
la source

Réponses:

734

myfun(*some_tuple)fait exactement ce que vous demandez. L' *opérateur décompresse simplement le tuple (ou tout autre itérable) et les passe comme arguments positionnels à la fonction. En savoir plus sur le déballage des arguments .

Alex Martelli
la source
8
L'opérateur * décompresse simplement le tuple et les passe comme arguments positionnels à la fonction. Voir plus ici: docs.python.org/3/tutorial/…
john_mc
4
Notez que la même syntaxe peut être utilisée pour les listes ainsi que pour les tuples.
brendon-ai
J'ai trouvé que vous pouvez faire la même chose avec les listes (en fait, toutes les itérables, y compris les chaînes), sans savoir comment leur mutabilité affecte les choses. Ce serait intéressant à examiner.
wcyn
52

Notez que vous pouvez également développer une partie de la liste des arguments:

myfun(1, *("foo", "bar"))
Valentas
la source
13
Il semble que vous ne pouvez le faire que si le tuple développé est après les arguments normalement fournis - l'interprète n'aime pas quand je fais cela:some_func(*tuple_of_stuff, another_argument)
Tom Galvin
6
@Quackmatic Le fait d'avoir le tuple étendu dans n'importe quel endroit semble fonctionner correctement dans Python 3.5.1
River
1
@Quackmatic seconding @River, cela fonctionne très bien en Python 3.5.4: def func(a,b,c,d): print(a,b,c,d)avecargs = ('fee', 'fi', 'fo'); func(*args, 'fum')
R. Navega
15

Jetez un œil au tutoriel Python section 4.7.3 et 4.7.4 du . Il parle de passer des tuples comme arguments.

J'envisagerais également d'utiliser des paramètres nommés (et de passer un dictionnaire) au lieu d'utiliser un tuple et de passer une séquence. Je trouve que l'utilisation d'arguments positionnels est une mauvaise pratique lorsque les positions ne sont pas intuitives ou qu'il existe plusieurs paramètres.

Uri
la source
8

Il s'agit de la méthode de programmation fonctionnelle. Il soulève la fonctionnalité d'extension de tuple du sucre de syntaxe:

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

Exemple d'utilisation:

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'

curry redefiniton of apply_tupleenregistre beaucoup d' partialappels à long terme.

Dominykas Mostauskis
la source
5
Ce n'est pas utile pour un débutant. Il utilise des modules tiers et fait d'autres trucs déroutants ...
gberger
gberger, lambda f, t: f(*t)n'utilise pas de modules tiers et je suis un débutant en Python et cela m'est utile. Il s'agit d'une pure approche fonctionnelle. Si vous n'utilisez pas ce style, cette réponse n'est pas pour vous.
Dominykas Mostauskis
1
toolz est tiers, c'est ce que je voulais dire
gberger
5
Toutes les réponses ne doivent pas être pour un débutant
Jordan
1
Pour l'exemple que vous avez donné, on peut utiliser starmap docs.python.org/3.7/library/itertools.html#itertools.starmap
Bo.