2010-01-03 34 views
250

有沒有辦法將Python元組展開成函數 - 作爲實際參數?將元組展開爲參數

例如,這裏expand()確實神奇:

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

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

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

我知道一個可以定義爲myfunmyfun((a, b, c)),但當然也有可能是遺留代碼。 謝謝

回答

486

myfun(*tuple)確實正好你的要求。

枝節問題:用作您的標識符內建類型的名稱,如tuplelistfileset,來回如此 - 這是可怕的實踐,它回來,當你最不咬你期待它, 所以只是養成積極的習慣避免用你自己的標識符隱藏內建名稱。

+1

您能否提供一個解釋,爲什麼星號運算符會做什麼要求? – winklerrr 2017-05-19 08:37:38

+1

*運算符只是解開元組並將它們作爲位置參數傳遞給函數。請參閱更多:https://docs.python.org/3/tutorial/controlflow.html#tut-unpacking-arguments – 2017-06-30 21:09:38

+0

請注意,相同的語法可以用於列表以及元組。 – 2017-08-17 13:22:08

12

看一看the Python tutorial第4.7.3和4.7.4節。它談論傳遞元組作爲參數。

我還會考慮使用命名參數(和傳遞字典),而不是使用元組並傳遞序列。當位置不直觀或有多個參數時,我發現使用位置參數是一種不好的做法。

27

請注意,您也可以展開參數列表的一部分:

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

看來只有當擴展元組在正常提供的參數之後才能做到這一點 - 當我這樣做時,解釋器不喜歡它:'some_func(* tuple_of_stuff,another_argument)' – Quackmatic 2015-04-19 20:46:03

+3

@Quackmatic在任何擴展元組中位置似乎在Python 3.5.1中工作正常 – River 2016-06-13 13:00:14

2

這是函數式編程方法。它舉起元組擴展功能進行語法糖:

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

用法示例:

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' 

curryapply_tuple redefiniton節省了大量的,從長遠來看partial電話。

+1

這對初學者沒有幫助。它使用第三方模塊並執行其他令人困惑的事情...... – gberger 2017-05-26 14:09:06

+0

gberger,'lambda f,t:f(* t)'不使用第三方模塊,我是一個Python初學者,這對我很有幫助。這是一種純粹的功能性方法。如果你不使用這種風格,那麼這個答案不適合你。 – 2017-05-28 07:32:31

+0

toolz是第三方,是我的意思 – gberger 2017-05-30 08:54:57

0

我遇到了類似的問題,並創建了擴展固定功能的函數。希望這可以幫助。

def run_argtup(func, argvalues): 
    """ 
    Execute any functions with their arguments in tuple. 

    :param func: 
    :param argvalues: 
    :return: 
    """ 
    argnames = get_func_argnames(func) 
    if len(argnames) != len(argvalues): 
     raise ValueError("Length of args doens't match.") 
    for argn, argv in zip(argnames, argvalues): 
     exec('{}=argv'.format(argn)) 
    return eval('func(%s, %s)' % argnames)