制作字典列表按值传递

Posted

技术标签:

【中文标题】制作字典列表按值传递【英文标题】:Making a list of dictionaries pass-by-value 【发布时间】:2012-11-28 03:10:59 【问题描述】:

我对字典列表有点头疼。

def funk(x):
    for i in x:
        i['a'] += 1
        print i

list1 = ['a':1, 'b':2, 'a':3, 'b':4]
funk(list1)
print list1

这将输出:

'a': 2, 'b': 2
'a': 4, 'b': 4
['a': 2, 'b': 2, 'a': 4, 'b': 4]

但我想要这个:

'a': 2, 'b': 2
'a': 4, 'b': 4
['a':1, 'b':2, 'a':3, 'b':4]

如何让list1 保持原样? 例如:['a':1, 'b':2, 'a':3, 'b':4]

【问题讨论】:

首先,Python 中的一切都是按值传递的。但是 Python 中的每个值都是指向对象的指针。 【参考方案1】:

funk() 可以复制x 并修改该副本,而不是修改原始x

import copy

def funk(x):
    x = copy.deepcopy(x)
    for i in x:
        i['a'] += 1
        print i

list1 = ['a':1, 'b':2, 'a':3, 'b':4]
funk(list1)
print list1

【讨论】:

你应该说deepcopy。由于x 是一个包含dicts 的列表,因此浅拷贝不会削减它。 我没有尝试过,但我高度怀疑x 中的一个简单的copy 是否适用于此。无论你是否复制列表,你在 for 循环中迭代的对象都是完全相同的......所以当你改变一个对象时,它仍然应该出现。 @NPE -- 也许你应该再试一次;-)。我刚刚尝试过,我从最终的print list1 得到的结果如下:['a': 2, 'b': 2, 'a': 4, 'b': 4]。请注意,a 元素已递增。 @mgilson:已经有了,你是对的。暂时失明。很抱歉浪费您的时间。 :)【参考方案2】:

在我看来,字典的copy 方法可能对您有所帮助:

def funk(x):
    for i in x:
        new_dict = i.copy()
        new_dict['a'] += 1
        print new_dict

【讨论】:

【参考方案3】:

显然,它是否可行取决于您的操作的复杂性/目标,但不要就地修改您的列表,而是使用list comprehension 创建一个新列表:

def funk(x):
    return [key: value+1 if key == "a" else value for key, value in i.items() for i in x]

在您的示例中,您正在打印值,因此这将没有用,但如果您的意图可以通过拥有一个新的、更改的 dicts 列表来填充,那么这可能是最好的路线。

【讨论】:

我认为它应该是 value+1 if key == 'a' else value 而不是 value if key+1 == 'a' ...。否则,我支持这个答案(+1) @mgilson 确实,只是我不小心。

以上是关于制作字典列表按值传递的主要内容,如果未能解决你的问题,请参考以下文章

按值传递列表以发挥作用

列表是按值传递的吗?

按值传递递归?

按值传递或按引用传递

请说明golang类型是不是按值传递

在lisp中按值传递参数