python - 共享可变的问题?

标签 python

def set_if_not_there(d, fields, default_value=None):
    for field in fields:
        if not field in d:
            d[field] = default_value

d = { }

set_if_not_there(d, ['cnt1', 'cnt2'], 0)
set_if_not_there(d, ['tags1', 'tags2'], [])

d['cnt1'] += 1
d['tags1'].append('work')

print d

输出是:

{'tags2': ['work'], 'cnt2': 0, 'cnt1': 1, 'tags1': ['work']}

如您所见,tags1tags2 实际上指的是同一个列表,这不是故意的。 cnt1cnt2 工作正常。

如何实现 set_if_not_there 以便创建可变对象的副本,但仅在需要时创建?也就是说,如果默认值是“标量”(整数、字符串、None、...),则不需要副本,但对于列表和字典,则需要副本。

最佳答案

使用工厂函数代替默认值:

def set_if_not_there(d, fields, default_factory=None):
    if default_factory is None:
        default_factory = lambda: None
    for field in fields:
        if not field in d:
            d[field] = default_factory()

并传入可调用对象(如函数或 lambda,或默认类型):

set_if_not_there(d, ['cnt1', 'cnt2'], int)
set_if_not_there(d, ['tags1', 'tags2'], list)

int() 返回0list() 返回一个新的空列表。

这就是标准库collections.defaultdict()例如,类型也是如此。

演示:

>>> d = {}
>>> set_if_not_there(d, ['cnt1', 'cnt2'], int)
>>> set_if_not_there(d, ['tags1', 'tags2'], list)
>>> d['cnt1'] += 1
>>> d['tags1'].append('work')
>>> print d
{'tags2': [], 'cnt2': 0, 'cnt1': 1, 'tags1': ['work']}

关于python - 共享可变的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19343752/

相关文章:

python - 迭代长列表的集合

python -\r(回车)在 Python 中如何工作

python - 基于条件的 Pandas 数据框计算

python - django queryset 返回 "classname object"而不是 DB 值

python unicode 用空字符串替换反斜杠 u

python - TensorFlow:训练时参数不更新

python - 对没有年份但有 2 月 29 日的字符串日期列表进行排序

python - 使用Python计算坡度的程序

python - 如何在 URL 的 python 瓶中加载静态文件

python - 从代理服务器后面使用 ez_setup.py 安装 Python 的 easy_install