【问题标题】:Some strange behavior Python list and dict一些奇怪的行为 Python list 和 dict
【发布时间】:2013-04-19 19:09:37
【问题描述】:

谁能解释为什么列表会发生这种情况以及在附加到另一个列表后如何清理列表?

>>> t = {}
>>> t["m"] = []
>>> t
{'m': []}
>>> t["m"].append('qweasdasd aweter')
>>> t["m"].append('asdasdaf ghghdhj')
>>> t
{'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']}
>>> r = []
>>> r.append(t)
>>> r
[{'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']}]
>>> t["m"] = []
>>> r
[{'m': []}]

【问题讨论】:

  • 你调用这个行为奇怪,假设当你append到r时python会隐式复制整个字典,在几乎所有情况下,Python什么都不做,除非你已经明确告诉它了。

标签: python list dictionary


【解决方案1】:

这是正常行为。 Python 使用引用来存储元素。 当您执行r.append(t) 时,python 会将t 存储在r 中。如果稍后修改tr中的t也会被修改,因为它是同一个对象。

如果您想让t 独立于存储在r 中的值,您必须复制它。查看copy 模块。

【讨论】:

    【解决方案2】:

    当您调用r.append(t) 时,您的意思是“在列表r 的末尾存储对t 中存储的值的引用”。字典t引用没有被复制,所以当你修改t时你修改了r引用的数据。

    这里可以更清楚地看到这种行为:

    >>> x = []
    >>> y = x
    >>> x.append(1)
    >>> y
    [1]
    

    这会将y 设置为x 引用的值,因此当x 更改时,y 似乎也会更改。

    【讨论】:

      【解决方案3】:

      字典在 Python 中是可变的,取而代之的是复制

      >>> import copy
      >>> r.append(copy.copy(t))
      >>> t
      {'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']}
      >>> r
      [{'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']}]
      >>> t["m"]=None
      >>> r
      [{'m': ['qweasdasd aweter', 'asdasdaf ghghdhj']}]
      

      【讨论】:

        【解决方案4】:

        你可以尝试这样做:

        import copy
        r.append(copy.deepcopy(t))
        

        这应该可行。

        干杯

        【讨论】:

          【解决方案5】:

          这是正常的。当您将对象分配给变量时,python 不会将该对象复制到您的变量中。它只会将原始对象的引用分配给您的新对象。

          In [1]: a = [1,2]   
          In [2]: b = a
          In [3]: a.remove(1)
          In [4]: b
          Out[4]: [2]
          

          这里 b 将只保存原始列表 a 的引用。如果你想覆盖这个行为,你可以使用 copy 模块。

          In [7]: import copy
          In [8]: a = [1,2]
          In [9]: b = copy.deepcopy(a)
          In [10]: a.remove(1)
          In [11]: b
          Out[11]: [1, 2]
          

          deepcopy 复制所有内容,包括单个元素。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-10-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-13
            • 2020-03-24
            相关资源
            最近更新 更多