【问题标题】:Creating Python variables that are independent of each other创建相互独立的 Python 变量
【发布时间】:2013-05-03 15:34:46
【问题描述】:

如果我有这个 Python 代码:

foo = [3, 5, 9]
bar = foo
bar.append(9)
print(foo)

返回

[3, 5, 9, 9]

这肯定意味着当我将9 附加到bar 时,它也影响了foo。如何使变量bar 等于foo,但是当我编辑bar 时,它不会影响foo

【问题讨论】:

    标签: python list


    【解决方案1】:

    使用deepcopy:

    >>> from copy import deepcopy
    >>> foo = [3, 5, 9]
    >>> bar = deepcopy(foo)
    >>> bar.append(9)
    >>> print(foo)
    [3, 5, 9]
    >>> print bar
    [3, 5, 9, 9]
    

    【讨论】:

      【解决方案2】:

      在创建原始副本的同时删除对其的所有引用(因此您无法编辑原始副本)时,您使用深层复制。

      http://docs.python.org/2/library/copy.html

      import copy
      bar = copy.deepcopy(foo)
      

      【讨论】:

        【解决方案3】:

        您正在更改一个可变值,因此您需要进行显式复制:

        bar = list(foo)
        

        bar = foo[:]
        

        在 Python 中为名称赋值时,您只需将 reference 存储到该值。在不创建列表副本的情况下,foobar 都引用了同一个列表。

        对于非可变值,这不是问题;您替换对字符串的引用以指向不同的值。

        但是列表(以及dictset 以及大多数类的实例)是可变的。你没有改变foo,你改变了foo指的是。你做了foo.append(9),Python 将其视为:

        • 找到foo所指的值。
        • 在该值上找到属性.append。这会返回一个列表实例的方法。
        • 调用方法,传入值9。这会改变列表。

        Python 名称本身只不过是标签,指向实际值。您可以将值视为气球,将名称视为小纸标签,而分配是将标签绑定到气球的行为。 bar = foo 创建了第二个纸质标签,它与完全相同的气球绑定。

        请参阅此older answer of mine,我在其中进一步推动了气球隐喻。

        【讨论】:

        • +1,打败我。我个人更喜欢使用 list(),因为它适用于任何可迭代对象,而且我觉得它更具可读性(这得到了 SO 上询问 [:] 做什么的问题数量的支持)。
        • 为什么 ideone 上的 Python 代码:ideone.com/QIjOsD 没有产生预期的结果(三个 1,而不是四个)?我是不是做错了什么?
        • @Lewis:嵌套列表。您只复制了 outer 列表。外部列表不过是一系列动态的纸质标签,按顺序编号。并且这些编号的标签是更多的字符串到更多的值,每个另一个列表。复制刚刚复制到标签上的外部列表,包括与它们绑定的新字符串。使用 copy 模块创建深层副本 (b = copy.deepcopy(a)),或使用列表推导:b = [elem[:] for elem in a]。列表推导式创建每个包含列表的浅表副本,生成一个新的外部列表,其中这些浅表副本作为元素。
        • @MartijnPieters 抱歉,我在您编辑评论时写了评论 :)
        【解决方案4】:

        你复制一份:

        bar = foo[:]  #copy of foo
        bar.append(9)
        

        这与 python 如何处理赋值有关。分配说“将右侧的对象存储在本地命名空间中左侧的名称下”。因此,在您的情况下,您有 foo 和 bar 引用同一个对象,这就是为什么附加到一个对象也会影响另一个对象。

        当使用操作符通常对对象进行操作时,不可变对象会变得更有趣(例如+=)。例如,请参阅my answer here 和更多解释。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-10-28
          • 2022-07-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-27
          • 1970-01-01
          相关资源
          最近更新 更多