为了账号安全,请及时绑定邮箱和手机立即绑定

避免默认参数为空列表的pythonic方法是什么?

避免默认参数为空列表的pythonic方法是什么?

胡子哥哥 2019-10-18 11:07:50
有时,使用默认参数(一个空列表)似乎很自然。然而,在这些情况下,Python给出了意外的行为。例如,如果我有一个功能:def my_func(working_list = []):    working_list.append("a")    print(working_list)第一次调用它时,默认值将起作用,但是此后的调用将更新现有列表(每个调用一个“ a”)并打印更新的版本。那么,获得我想要的行为(每次调用都有一个新列表)的pythonic方法是什么?
查看完整描述

3 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

def my_func(working_list=None):

    if working_list is None: 

        working_list = []


    working_list.append("a")

    print(working_list)

文档说您应该将其None用作默认值,并在函数主体中对其进行显式测试。


查看完整回答
反对 回复 2019-10-18
?
PIPIONE

TA贡献1829条经验 获得超9个赞

如果该函数的目的是修改通过传递的参数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习惯执行此操作,则完全没有必要-您始终可以将多个值作为元组返回。


如果您这样做是为了有效地构建一长串结果而不创建中间列表,请考虑将其作为生成器编写并result_list.extend(myFunc())在调用时使用。这样,您的调用约定仍然非常干净。


经常更改可选arg的一种模式是递归函数中的隐藏“ memo” arg:


def depth_first_walk_graph(graph, node, _visited=None):

    if _visited is None:

        _visited = set()  # create memo once in top-level call


    if node in _visited:

        return

    _visited.add(node)

    for neighbour in graph[node]:

        depth_first_walk_graph(graph, neighbour, _visited)


查看完整回答
反对 回复 2019-10-18
  • 3 回答
  • 0 关注
  • 643 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信