搜尋

首頁  >  問答  >  主體

python小白 問關於a+=a 和a=a+a的差別

第一段程式碼:

#
# -*- coding:gb2312 -*-

a = [100]

def test(num):
    num += num #第一段代码
    print(num)
    
test(a)
print(a)

執行結果:

##第二段程式碼:

#
# -*- coding:gb2312 -*-

a = [100]

def test(num):
    num = num + num  #这个地方改了一下
    print(num)
    
test(a)
print(a)

執行結果:

##我的問題:
num = num不應該直接等價於mun = num num 麼
為什麼算出來結果卻是不一樣的?這個是什麼情況

三叔三叔2779 天前1185

全部回覆(4)我來回復

  • 大家讲道理

    大家讲道理2017-06-13 09:26:36

    你可以嘗試進行這樣的操作,

    In [1]: a = [100]
    
    In [2]: b = [100]
    
    In [3]: id(a)
    Out[3]: 79308552L
    
    In [4]: id(b)
    Out[4]: 79342728L
    
    In [5]: a += a
    
    In [6]: b = b + b
    
    In [7]: id(a)
    Out[7]: 79308552L
    
    In [8]: id(b)
    Out[8]: 79341192L

    透過id()這個函數可以得到變數所分配的記憶體位址。透過實驗發現使用了+的變數位址發生了變化,也就是你所說的num+=num與num=num+num不等價
    但是,當做如下騷操作時候又會發現啪啪啪打臉

    In [19]: a = (0,)
    
    In [20]: b = (0,)
    
    In [21]: id(a)
    Out[21]: 82230688L
    
    In [22]: id(b)
    Out[22]: 82208920L
    
    In [23]: a += a
    
    In [24]: b = b + b
    
    In [25]: id(a)
    Out[25]: 79268296L
    
    In [26]: id(b)
    Out[26]: 79328392L

    分配的位址似乎一直在改變。
    原因在於,Python中的資料結構分為可變(mutable)和不可變(immutable)。
    對於可變類型,=和+=有著明顯的不同,如上面的list:
    +表示連接操作,+=表示追加
    對於不可變類型,=和+=就是一樣的操作,如上面的tuple
    可變類型與不可變類型的本質在於記憶體空間是否可變~

    回覆
    0
  • PHP中文网

    PHP中文网2017-06-13 09:26:36

    首先看出差別在於

    In [26]: def test(num):
        ...:     num = num + num
        ...:     print (num)
        ...:
    
    In [27]: def test1(num):
        ...:     num += num
        ...:     print (num)
        ...:
    
    In [28]: import dis
    
    In [29]: dis.dis(test)
      2           0 LOAD_FAST                0 (num)
                  3 LOAD_FAST                0 (num)
                  6 BINARY_ADD  #区别在这儿
                  7 STORE_FAST               0 (num)
    
      3          10 LOAD_FAST                0 (num)
                 13 PRINT_ITEM
                 14 PRINT_NEWLINE
                 15 LOAD_CONST               0 (None)
                 18 RETURN_VALUE
    
    In [30]: dis.dis(test1)
      2           0 LOAD_FAST                0 (num)
                  3 LOAD_FAST                0 (num)
                  6 INPLACE_ADD  #看这儿
                  7 STORE_FAST               0 (num)
    
      3          10 LOAD_FAST                0 (num)
                 13 PRINT_ITEM
                 14 PRINT_NEWLINE
                 15 LOAD_CONST               0 (None)
                 18 RETURN_VALUE
    

    可以看出分別呼叫的方法不同,分別是__add__,__iadd__
    加法運算子會計算出新的object來賦值給num
    增量賦值運算子修改原來的引用

    參考這裡: https://stackoverflow.com/que...

    回覆
    0
  • 滿天的星座

    滿天的星座2017-06-13 09:26:36

    Remember that arguments are passed by assignment in Python.

    傳參數在python是用assignment 不是reference,所以你傳a過去函數時傳的是a的值,而不是a本身。若要改動a本身就需要用return傳值回來

    a = [100]
    
    def test(num):
        num = num + num  #这个地方改了一下
        return(num)      #这个地方再改了一下
        
    print(test(a))       #傳值回來
    print(a)
    a = test(a)
    print(a)
    

    結果:

    [100, 100]
    [100]
    [100, 100]
    

    回覆
    0
  • 世界只因有你

    世界只因有你2017-06-13 09:26:36

    在python中,a=a+b是先建立一個新的物件並讓變數a引用這個對象,a+=b是讓a所引用的物件的變成a+b的值

    回覆
    0
  • 取消回覆