Python 分配规则

Python 分配规则,python,python-3.x,Python,Python 3.x,我注意到作业中有一种(似乎)奇怪的行为,这导致我多次犯编程错误 首先请参见以下示例: >>> i = 0 >>> t = (i,) >>> t (0,) >>> i += 1 >>> t (0,) 与预期一样,t的唯一元素的值不会改变,即使在i的值增加之后也是如此 现在请参见以下内容: >>> l = [0] >>> t = (l,) >>> t ([

我注意到作业中有一种(似乎)奇怪的行为,这导致我多次犯编程错误

首先请参见以下示例:

>>> i = 0
>>> t = (i,)
>>> t
(0,)
>>> i += 1
>>> t
(0,)
与预期一样,
t
的唯一元素的值不会改变,即使在
i
的值增加之后也是如此

现在请参见以下内容:

>>> l = [0]
>>> t = (l,)
>>> t
([0],)
>>> l[0] += 1
>>> t
([1],)  # <- ?
。。。我知道它的值已经改变了,但在前面的示例中不是这样,在递增时只显式引用
l

我有两个问题:

  • 为什么会这样
  • 关于这一点,我有没有特别的规定

  • 这是因为整数是不可变的,列表是可变的

    >>> i = 0
    >>> t = (i,)
    >>> t[0] is i  # both of them point to the same immutable object
    True
    >>> i += 1  # We can't modify an immutable object, changing `i` simply 
                # makes it point to a new object 2.
                # All other references to the original object(0) are still intact.
    >>> i
    1
    >>> t       # t still points to the same 0
    (0,)
    >>> x = y = 1
    >>> id(x),id(y)
    (137793280, 137793280)
    >>> x += 1
    >>> id(x),id(y)       #y still points to the same object
    (137793296, 137793280)
    
    有关列表:

    >>> l = [0]
    >>> t = (l,)       
    >>> t[0] is l #both t[0] and l point to the same object [0]
    True
    >>> l[0] += 1 # modify [0] in-place
    >>> t
    ([1],)
    >>> l
    [1]
    #another exmple
    >>> x = y =[]    # x, y point to the same object
    >>> x.append(1)  # list.append modifies the list in-place
    >>> x, y          
    ([1], [1]) 
    >>> x = x + [2]  # only changes x, x now points to a new object
    >>> x, y
    ([1, 2], [1])
    

    在第二个示例中,
    t
    (元组)包含对
    l
    (列表)的引用。当您执行
    l[0]+=1
    时,您正在更改列表,但元组仍然保留对列表的引用。在第一个示例中,当您执行
    i+=1
    时,实际上是在创建一个元组没有引用的新整数。请看我不久前写的关于
    +=
    运算符及其实际实现方式的更深入的解释。

    因此,我们应该注意的是,他是在处理可变对象(列表、集合等)还是不可变对象(字符串、整数、元组…)?还有一个事实,元组是不可变的;如果元组中存储的对象是可变对象,但它没有实现
    \uuuu iadd\uuuu
    ,则该操作仍然不起作用;但是,使用自定义的
    \uuu iadd\uuuu
    方法(它修改
    self
    )它确实可以修改。@doukremt您可以从可变对象的任何引用(仅限就地操作,
    附加
    扩展
    +=/code>)修改可变对象,当修改一个不可变对象时,总是返回一个新对象,而所有其他引用仍然指向旧对象;不管怎样,提到可变/不可变确实会使人们对所发生的事情产生混淆。(不是我投了反对票。)任何作业都只意味着复制一份推荐信。任何Python变量都是作为键的字符串和绑定到键的引用值。大+1用于解释
    +=
    =>之间的区别+
    
    >>> l = [0]
    >>> t = (l,)       
    >>> t[0] is l #both t[0] and l point to the same object [0]
    True
    >>> l[0] += 1 # modify [0] in-place
    >>> t
    ([1],)
    >>> l
    [1]
    #another exmple
    >>> x = y =[]    # x, y point to the same object
    >>> x.append(1)  # list.append modifies the list in-place
    >>> x, y          
    ([1], [1]) 
    >>> x = x + [2]  # only changes x, x now points to a new object
    >>> x, y
    ([1, 2], [1])