Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 共享可变表的问题?_Python - Fatal编程技术网

Python 共享可变表的问题?

Python 共享可变表的问题?,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

输出为:

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
正如您所看到的,
tags1
tags2
实际上引用的是同一个列表,这是不需要的
cnt1
cnt2
工作正常


如果不在那里,我如何实现
set\u
,以便仅在需要时创建可变表的
副本
?也就是说,如果默认值是“标量”(int,string,
None
,…),则不需要任何副本,但对于列表和dict,则需要副本。

使用工厂函数而不是默认值:

{'tags2': ['work'], 'cnt2': 0, 'cnt1': 1, 'tags1': ['work']}
和传入可调用项(如函数、lambda或默认类型):

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

例如,这也是标准库类型所做的

演示:


您只需要复制。deepcopy

>>> 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']}
结果:

import copy
def set_if_not_there(d, fields, default_value=None):
    for field in fields:
        if not field in d:
            d[field] = copy.deepcopy(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': [], 'cnt2': 0, 'cnt1': 1, 'tags1': ['work']}
您将获得:

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

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

print d
如果您确实希望避免导入**,可以尝试:

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

同样有效

+1我需要将这种方法印在脑海中,因为它充满了优点!谢谢任何与
default\u factory=default\u factory或lambda:None
?如果不在那里(d,['cnt1',cnt2'],False)(您打算改为使用
lambda:False
),则不会检测到类似
set\u的错误。
set_if_not_there(d, ['cnt1', 'cnt2'], 0)
set_if_not_there(d, ['tags1', 'tags2'], [0,1])

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

print d
{'tags2': [0, 1], 'cnt2': 0, 'cnt1': 1, 'tags1': [0, 1, 'work']}
def set_if_not_there(d, fields, default_value=lambda:None):
    for field in fields:
        if not field in d:
            d[field] = default_value()

d = { }

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