首頁  >  問答  >  主體

据说在 python 下,某个情况下 "i += x" 不等于 "i = i + x"?

某个不愿理透露姓名的大大跟我说:

小伙子啊,你的代码有潜在的 bug 啊,i += x 会粗问题的。我思考了良久,都不得要领。

那么请问,什么情况下 "i += x" 不等于 "i = i + x"?

迷茫迷茫2761 天前763

全部回覆(8)我來回復

  • 大家讲道理

    大家讲道理2017-04-17 13:50:00

    看看下面兩段程式碼的比較:

    代碼1:

    >>> l1=range(3)
    >>> l2=l1
    >>> l2+=[4]
    >>> l1
    [0, 1, 2, 4]
    >>> l2
    [0, 1, 2, 4]
    

    代碼2:

    >>> l2=l1
    >>> l2=l2+[4]
    >>> l1
    [0, 1, 2]
    >>> l2
    [0, 1, 2, 4]
    

    具體的解釋看這裡:http://stackoverflow.com/questions/2347265/why-does-behave-unexpectedly-on-lists

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:50:00

    很明顯,就像2樓所說。
    代碼1 l2 = l1,l2 += [4],操作的都是l1,類似指針,引用神馬的,理解不了就這麼想就可以了。
    代碼2 l2 = l1,l2 = l2 + [4],這很明顯是對l2進行重新賦值。你可以這樣寫l3 = l2 + [4],l2 += [4]。然後就知道結果了。
    python的深拷貝和淺拷貝,可以了解一下

    2樓stackoverflow裡面有一個很不錯的答案,直接用id()看記憶體位址

    >>> l = []
    >>> id(l)
    13043192
    >>> l += [3]
    >>> id(l)
    13043192
    >>> l = l + [3]
    >>> id(l)
    13059216
    

    不用太糾結,直接看記憶體位址就一目了然。
    id是python內建函數,what's id? ...

    'id' is a bad variable name in Python

    id() is a fundamental built-in:
    Help on built-in function id in module builtin:

    id(...)
    
        id(object) -> integer
    
        Return the identity of an object.  This is guaranteed to be unique among
        simultaneously existing objects.  (Hint: it's the object's memory
        address.)
    

    回覆
    0
  • ringa_lee

    ringa_lee2017-04-17 13:50:00

    能想到的就是某些類別實現了__iadd__ 且跟__add__ 行為不一樣,list 的+= 就是一個例子,普通+ 會回傳一個新的list 實例,而+= 是直接操作list 本身。

    如果能確定 ix 就是兩個數,說 i += x 會出問題那就是有些吹毛求疵、教條主義了。

    回覆
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:50:00

    主要看i ,如果i是表達式
    i+=x 中i 只計算一次
    i = i+x i要計算2次

    那麼,如果i表達式中有修改變量, i = i+x 中兩個i的值可能是不同的

    a[i++] += 5         // i 执行一次求值
    a[i++] = a[i++] + 5 // i 执行两次求值
    

    這個範例在各種文法書裡應該比較常見

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-17 13:50:00

    以上是針對引用型別的,值型別應該是沒有差別的吧。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 13:50:00

    核心問題就是要防止副作用。讓程式碼的行為一致。

    回覆
    0
  • 迷茫

    迷茫2017-04-17 13:50:00

    這裡樓主有些誤解啊,i += x,這是一種語法糖,真正的展開後的樣子是啥樣子呢?
    在c語言裡, i += x 的真實的樣子是 i = i+x, 這裡i是被重新賦值了,那麼i的指標位址會變的.
    但Python裡不是這樣子的,i += x 的真實樣子是 i.extend(x), 這裡i的指針位址沒變,只是i的值被改變了而已。

    refer:http://stackoverflow.com/questions/2347265/why-does-behave-unexpectedly-on-lists
    thank to : @WKPlus

    回覆
    0
  • 高洛峰

    高洛峰2017-04-17 13:50:00

    4樓說的太對了,兩個不同文件的MD5值還有幾率相同呢,問題是你碰見過麼。

    回覆
    0
  • 取消回覆