Tupel in Argumente erweitern

411

Gibt es eine Möglichkeit, ein Python-Tupel zu einer Funktion zu erweitern - als tatsächliche Parameter?

Zum Beispiel macht hier expand()die 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")

Ich weiß, man könnte definieren myfunals myfun((a, b, c)), aber natürlich kann es Legacy-Code geben. Vielen Dank

AkiRoss
quelle

Antworten:

733

myfun(*some_tuple)macht genau das, was Sie verlangen. Der *Operator entpackt einfach das Tupel (oder ein beliebiges iterierbares) und übergibt es als Positionsargumente an die Funktion. Lesen Sie mehr über das Entpacken von Argumenten .

Alex Martelli
quelle
8
Der Operator * entpackt das Tupel einfach und übergibt es als Positionsargument an die Funktion. Weitere Informationen finden
Sie
4
Beachten Sie, dass dieselbe Syntax sowohl für Listen als auch für Tupel verwendet werden kann.
brendon-ai
Ich habe festgestellt, dass Sie dasselbe mit Listen tun können (in der Tat alle iterierbaren, einschließlich Zeichenfolgen), ohne sicher zu sein, wie sich ihre Veränderlichkeit auf die Dinge auswirkt. Das wäre interessant zu untersuchen.
wcyn
52

Beachten Sie, dass Sie auch einen Teil der Argumentliste erweitern können:

myfun(1, *("foo", "bar"))
Valentas
quelle
13
Es scheint, dass Sie dies nur tun können, wenn das erweiterte Tupel hinter den normalerweise angegebenen Argumenten steht - der Interpreter mag es nicht, wenn ich das tue:some_func(*tuple_of_stuff, another_argument)
Tom Galvin
6
@Quackmatic Das erweiterte Tupel an einem beliebigen Ort zu haben, scheint in Python 3.5.1
River
1
@Quackmatic Seconding @ River, dies funktioniert gut in Python 3.5.4: def func(a,b,c,d): print(a,b,c,d)mitargs = ('fee', 'fi', 'fo'); func(*args, 'fum')
R. Navega
15

Schauen Sie sich das Python-Tutorial in den Abschnitten 4.7.3 und 4.7.4 an. Es geht darum, Tupel als Argumente zu übergeben.

Ich würde auch in Betracht ziehen, benannte Parameter zu verwenden (und ein Wörterbuch zu übergeben), anstatt ein Tupel zu verwenden und eine Sequenz zu übergeben. Ich finde die Verwendung von Positionsargumenten eine schlechte Praxis, wenn die Positionen nicht intuitiv sind oder mehrere Parameter vorhanden sind.

Uri
quelle
8

Dies ist die funktionale Programmiermethode. Es hebt die Tupel-Erweiterungsfunktion aus dem Syntaxzucker heraus:

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

Anwendungsbeispiel:

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- Neudefinition apply_tuplespart partialauf lange Sicht viele Anrufe.

Dominykas Mostauskis
quelle
5
Dies ist für Anfänger nicht hilfreich. Es verwendet Module von Drittanbietern und macht andere verwirrende
Dinge
gberger lambda f, t: f(*t)verwendet keine Module von Drittanbietern und ich bin ein Python-Anfänger und dies ist hilfreich für mich. Dies ist ein rein funktionaler Ansatz. Wenn Sie diesen Stil nicht verwenden, ist diese Antwort nichts für Sie.
Dominykas Mostauskis
1
toolz ist ein Drittanbieter, meinte ich
gberger
5
Nicht jede Antwort muss für einen Anfänger sein
Jordanien
1
Für das Beispiel, das Sie gegeben haben, können Sie starmap docs.python.org/3.7/library/itertools.html#itertools.starmap
Bo verwenden.