默认参数是空列表的Python方法是什么?

有时似乎很自然有一个默认的参数,这是一个空的列表。 然而,Python在这些情况下会产生意想不到的行为

如果例如,我有一个function:

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 

是我如何做到的。

在这种情况下并不重要,但是您可以使用对象标识来testingNone:

 if working_list is None: working_list = [] 

你也可以利用如何在python中定义的布尔运算符:

 working_list = working_list or [] 

虽然如果调用者为working_list提供一个空的列表(这个列表为false),并且期望你的函数修改他给出的列表,这将意外地performance出来。

如果函数的意图是修改作为working_list传递的参数,请参阅HenryR的答案(= None,检查None内部)。

但是如果你不打算改变这个参数,只要用它作为列表的起点,你可以简单地复制它:

 def myFunc(starting_list = []): starting_list = list(starting_list) starting_list.append("a") print starting_list 

(或者在这个简单的例子中,只是print starting_list + ["a"]但我想这只是一个玩具的例子)

一般来说,改变你的参数是Python中不好的风格。 唯一完全预期会改变对象的函数是对象的方法。 更改可选参数更为罕见 – 仅在某些调用中发生的副作用才是真正的最佳界面?

  • 如果你从“输出参数”的C习惯做到这一点,那完全没有必要 – 你总是可以将多个值作为元组返回。

  • 如果你这样做,有效地build立一个长长的列表,而不用build立中间列表,可以考虑把它写成一个生成器,并在你调用它时使用result_list.extend(myFunc()) 。 这样你的调用约定仍然非常干净。

在一个可选的arg中进行变异的模式通常是在recursion函数中隐藏的“memo”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) 

现有的答案已经提供了所要求的直接解决scheme。 然而,由于这对于新的Python程序员来说是一个非常常见的错误,因此值得添加python行为的解释,这在“ Hitchhikers Guide to Python ”很好地总结为“ Mutable Default Arguments ”: http:// python -guide-pt-br.readthedocs.io/en/latest/writing/gotchas/

Quote:“ Python的默认参数在函数定义时被计算一次,而不是每次函数被调用(就像它在说,Ruby)。这意味着如果你使用一个可变的默认参数并改变它,你将会将这个对象调用到该函数的所有对象也是

示例代码来实现它:

 def foo(element, to=None): if to is None: to = [] to.append(element) return to 

我可能是脱离主题,但请记住,如果你只是想传递可变数量的参数,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} 

已经有好的和正确的答案。 我只是想给另一种语法来写你想做什么,当你想要创build一个默认的空列表的类:

 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 [] 

这段代码使用if else操作符语法。 我喜欢它,特别是因为它是一个没有冒号的整齐的小单线,等等,它几乎像一个正常的英语句子。 🙂

在你的情况下,你可以写

 def myFunc(working_list=None): working_list = [] if working_list is None else working_list working_list.append("a") print working_list