【问题标题】:Why is the attribute of dict immutable object, and the list in it is mutable object [closed]为什么dict的属性是不可变对象,而里面的列表是可变对象[关闭]
【发布时间】:2017-10-22 20:16:09
【问题描述】:

我在看探索 python。它有一个例子:

    >>> d1 = {'name': 'ethan', 'books': ['book1', 'book2', 'book3']}
    >>> d2 = d1.copy()
    >>> d2['name'] = 'peter'         
    >>> d2
    {'books': ['book1', 'book2', 'book3'], 'name': 'peter'}
    >>> d1
    {'books': ['book1', 'book2', 'book3'], 'name': 'Ethan'}

字典不是值键对象吗?为什么说name的值是不可变对象,所以d1的属性不会改变。

【问题讨论】:

  • 字典不是不可变的。该代码显式创建了一个单独的(尽管 shallow)副本。
  • name的值为字符串,不可变。但它在这里的任何地方都没有变异。 dictionary 是可变的,您可以告诉它将不同的值关联到给定的键。

标签: python


【解决方案1】:

字典copy 方法显式创建一个副本。这与可变性无关。试试

d2=d1

看看你的期望。此外,一个对象是可变的意味着你不能改变它。尝试改变一个元组,例如:

x=(1,2,3)
x[0]=4

注意 - 这与其他变量无关。事实上,试试:

(1,2,3)[0]=4

小修改

d1 的副本很浅,这意味着books 的列表仅复制了它的引用。因此,所有指向它的东西都会看到更改列表 - 两个字典。请注意,列表发生了变化,而不是字典。

【讨论】:

  • 但是如果我删除书籍会怎样。 D1 变了吗?
  • >>> d2['books'].remove('book2') >>> d2 {'books': ['book1', 'book3'], 'name': 'peter' } >>> d1 {'books': ['book1', 'book3'], 'name': 'ethan'}
  • @cclsr 您可以删除的原因是字典是可变的(可以更改)。同样,当您运行 d1.copy() 时,您正在创建一个 new, totally different 字典。其中一个的变化与另一个无关。 BUT,里面的列表没有复制,只是被两个人引用了!所以在这里,您将更改 list,它恰好被两个 dicts 所指向。
【解决方案2】:

因为,为了加快查找速度,python 会为字典的每个键计算一个 散列值。如果键对象是从其他不知道它被用作字典中的键的类中更改的,则不会通知字典,并且会在随后的查找中在错误的位置查找它。

【讨论】:

    猜你喜欢
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 1970-01-01
    • 2010-12-29
    • 2012-01-12
    • 2011-06-02
    • 1970-01-01
    相关资源
    最近更新 更多