【问题标题】:Why Python "append" is not behaving as expected?为什么 Python“附加”的行为不符合预期?
【发布时间】:2021-04-06 14:47:38
【问题描述】:

我有这段代码,我用它来将结构中包含列表的字典转换为字典列表,为内部列表的每个项目添加平面结构中的新列。这是我的代码:

origin = {
    "a":1,
    "b":2,
    "m":[
        {"c":3},
        {"c":4}
    ]
}
    
# separating the "flat" part of the structure
flat = dict()
for o in origin.keys():
    if not isinstance(origin[o], list):
        flat[o] = origin[o]

lines = list()
# starts receiving the 'flat' value, once the new lines will receive the same flat values.
new_line = flat

# getting the "non-flat" values and creating new dictionaries using the flat structure
for i in origin["m"]:
    k = list(i.keys())[0]
    v = list(i.values())[0]
    new_line[k] = v
    print(f"NEW_LINE: {str(new_line)}")
    lines.append(new_line)

print(f"LINES:\n{str(lines)}")

我期待这个:

NEW_LINE: {'a': 1, 'b': 2, 'c': 3}
NEW_LINE: {'a': 1, 'b': 2, 'c': 4}
LINES:
[{'a': 1, 'b': 2, 'c': 3}, {'a': 1, 'b': 2, 'c': 4}]

但我明白了:

NEW_LINE: {'a': 1, 'b': 2, 'c': 3}
NEW_LINE: {'a': 1, 'b': 2, 'c': 4}
LINES:
[{'a': 1, 'b': 2, 'c': 4}, {'a': 1, 'b': 2, 'c': 4}]

为什么?

【问题讨论】:

  • 你需要在字典后面附加一个copylines.append(new_line.copy()),否则它们都指向同一个对象。
  • 非常感谢@KrishnaChaurasia!

标签: python list append


【解决方案1】:

您需要将dictionary 对象的副本附加为lines.append(new_line.copy()),否则它们都指向同一个对象。

请注意,copy() 是对象的浅拷贝,您需要将 deepcopy() 用于嵌套对象。

the docs中阅读两者的区别。

浅拷贝和深拷贝的区别只与 复合对象(包含其他对象的对象,如列表或 类实例):

  • 浅拷贝构造一个新的复合对象,然后(到 尽可能)将引用插入其中找到的对象 原件。

  • 深拷贝构造一个新的复合对象,然后递归地, 将原始对象中的对象的副本插入其中。

【讨论】:

    猜你喜欢
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    相关资源
    最近更新 更多