有時似乎很自然有一個空列表的默認參數。但是Python在這些情況下會產生意想不到的行爲避免默認參數爲空列表的Python方法是什麼?
如果,例如,我有一個函數:
def myFunc(working_list = []):
working_list.append("a")
print working_list
第一次被調用時使用默認的工作,但之後呼叫將使用一個不斷更新的名單。
那麼,什麼是pythonic的方式來獲得我想要的行爲(每個電話的新清單)?
有時似乎很自然有一個空列表的默認參數。但是Python在這些情況下會產生意想不到的行爲避免默認參數爲空列表的Python方法是什麼?
如果,例如,我有一個函數:
def myFunc(working_list = []):
working_list.append("a")
print working_list
第一次被調用時使用默認的工作,但之後呼叫將使用一個不斷更新的名單。
那麼,什麼是pythonic的方式來獲得我想要的行爲(每個電話的新清單)?
def myFunc(working_list=None):
if working_list is None:
working_list = []
working_list.append("a")
print working_list
是我該怎麼做的。
這不是問題在這種情況下,但您可以使用對象標識來測試無:
if working_list is None: working_list = []
你也可以利用怎樣的布爾運算符或在Python定義:
working_list = working_list or []
雖然如果調用者爲working_list提供了一個空列表(其計數爲false),並且期望您的函數修改他提供的列表,但這種行爲會出乎意料。
我可能是脫離主題,但請記住,如果您只是想傳遞可變數量的參數,pythonic方式是傳遞一個元組*args
或字典**kargs
。這些是可選的,並且比語法myFunc([1, 2, 3])
更好。
如果你想傳遞一個元組:
def myFunc(arg1, *args):
print args
w = []
w += args
print w
>>>myFunc(1, 2, 3, 4, 5, 6, 7)
(2, 3, 4, 5, 6, 7)
[2, 3, 4, 5, 6, 7]
如果你想傳遞的字典:
def myFunc(arg1, **kargs):
print kargs
>>>myFunc(1, option1=2, option2=3)
{'option2' : 2, 'option1' : 3}
如果該功能的目的是修改爲working_list
傳遞的參數,請參閱HenryR的答案(=無,在裏面檢查無)。
但是,如果你不打算變異的說法,只是用它作爲出發點的列表,你可以簡單地複製:
def myFunc(starting_list = []):
starting_list = list(starting_list)
starting_list.append("a")
print starting_list
(或在這個簡單的例子只是print starting_list + ["a"]
但我猜這只是一個玩具的例子)
一般來說,變異你的參數是Python中的不良風格。唯一完全預期會改變對象的函數是該對象的方法。更改可選參數更爲罕見 - 僅在某些調用中發生的副作用纔是真正的最佳界面?
如果您從「輸出參數」的C習慣這樣做,這是完全沒有必要的 - 你可以隨時返回多個值作爲一個元組。
如果你這樣做,以有效地建立一個長列表的結果沒有建立中間名單,考慮寫作爲一個發電機,並使用result_list.extend(myFunc())
當你打電話給它。這樣你的調用約定仍然非常乾淨。其中突變可選ARG
一種模式是經常做的是遞歸函數隱藏的「備忘錄」 ARG:
def depth_first_walk_graph(graph, node, _visited=None):
if _visited is None:
_visited = set() # create memo once in top-level call
return if node in _visited
_visited.add(node)
for neighbour in graph[node]:
depth_first_walk_graph(graph, neighbour, _visited)
現有的答案已經提供了直接的解決方案要求。然而,由於這是一個新的Python程序員很常見的陷阱,值得補充爲什麼蟒蛇的行爲這樣解釋,這是很好的總結了「的漫遊指南到Python」爲「易變默認參數」:
報價:「Python的默認參數進行評估,一旦被定義的功能時,不會在每次調用函數時(就像是在說,紅寶石)這意味着,如果您使用的是可變的默認參數和變異它,你將和已經變異爲對該函數的所有未來調用該對象以及「
示例代碼來實現它:
提供def foo(element, to=None):
if to is None:
to = []
to.append(element)
return to
這兒已經好正確的答案。我只是想給另一種語法來寫你想做的事,我覺得更漂亮時,你比如想創建一個默認的空列表類的內容:
class Node(object):
def __init__(self, _id, val, parents=None, children=None):
self.id = _id
self.val = val
self.parents = parents if parents is not None else []
self.children = children if children is not None else []
這段代碼利用了,如果其他運營商的語法。我喜歡它,特別是因爲它是一個沒有冒號的整齊的小單線,等等,它幾乎像一個正常的英語句子。 :)
你的情況,你可以寫
def myFunc(working_list=None):
working_list = [] if working_list is None else working_list
working_list.append("a")
print working_list
如果任何人的興趣在爲什麼出現這種情況,請http://effbot.org/zone/default-values.htm – 2012-07-16 19:06:36
同樣的行爲發生了套,儘管你需要一個稍微複雜的例子來顯示它是一個bug。 – abeboparebop 2015-11-19 12:28:29