【问题标题】: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 中的每个值都是指向对象的指针。

标签: python pass-by-value


【解决方案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 确实,只是我不小心。
    猜你喜欢
    • 2013-02-28
    • 1970-01-01
    • 2020-02-09
    • 1970-01-01
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    相关资源
    最近更新 更多