python - 在函数调用之间未重新分配 Set
问题描述
就我而言,我尝试在递归函数调用和更新它之间传递一个集合。通过每次显式传递它作为参数,我希望集合在递归期间不断更新。
对于新的调用,我没有明确传递 set aa 参数,并期望res_set
将重定向到一个空的 set 对象。但是在多次调用该函数时,该集合正在更新,就好像 res_set = set()
不存在一样。
def some_recursion_withset(i, res_set = set()):
res_set.add(random())
if i > 0:
i -= 1
print(res_set)
some_recursion_withset(i, res_set)
return res_set
some_recursion_withset(3)
some_recursion_withset(1)
这里的输出是:
{0.12513618559206574}
{0.12513618559206574, 0.8224507177489353}
{0.12513618559206574, 0.8224507177489353, 0.7157637106872556}
{0.12513618559206574, 0.8224507177489353, 0.6921901499074943, 0.7157637106872556, 0.8116969360080692}
简化为一个最小的工作示例,为什么在这种情况下res_set = set()
被忽略?
from random import random
def some_func_withset(res_set = set()):
res_set.add(random())
return res_set
print(some_func_withset())
print(some_func_withset())
print(some_func_withset())
在这种情况下,输出是:
{0.9691623786355451}
{0.9691623786355451, 0.37884137576633103}
{0.9691623786355451, 0.37884137576633103, 0.4482797349507742}
我最感兴趣的是理解这种行为以及实现第一个递归部分的一些好的做法。
解决方案
来自Python 教程:
默认值仅评估一次。当默认值是可变对象(例如列表、字典或大多数类的实例)时,这会有所不同。例如,以下函数累积在后续调用中传递给它的参数:
res_set = set()
只评估一次,这是默认参数,在您的情况下是一个集合对象。当您使用带有默认参数的函数时,您总是得到相同的集合对象,并且由于您不断更新它,集合随着您插入的所有值而增长。
解决您的问题的方法是使用不可变对象作为金丝雀,然后检查您的论点是否是该金丝雀。如果是这种情况,则创建一个新集。在这种情况下使用None
是 Python 程序员的约定:
def some_func_withset(res_set = None):
if res_set is None:
res_set = set()
res_set.add(random())
return res_set
推荐阅读
- android - 基于现有布局以编程方式添加按钮
- javascript - 如何在混合 Javascript/Typescript 项目中引用“window”变量
- javascript - 如何让我的联系表在提交时发送电子邮件?
- mysql - 如何在 gulpfile 中将 mysqldump 与 --hex-blob 一起使用?
- angular - Object(...)(...).takeUntil 不是函数
- node.js - Sequelize 同步和 Node.js 不创建表
- mysql - 如何在mysql中创建表一次考虑多个约束?
- jupyter-notebook - Jupyter 中的非阻塞单元执行
- mysql - 尝试在 MySQL Workbench 中导入 sql 转储时使用 sql_mode 出现错误 1231 (42000)
- javascript - 如何访问文件外的函数