search

Home  >  Q&A  >  body text

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

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

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

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

迷茫迷茫2808 days ago801

reply all(8)I'll reply

  • 大家讲道理

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

    Look at the comparison of the two pieces of code below:

    Code 1:

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

    Code 2:

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

    See here for a detailed explanation: http://stackoverflow.com/questions/2347265/why-does-behave-unexpectedly-on-lists

    reply
    0
  • 伊谢尔伦

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

    Obviously, just like what the 2nd floor said.
    Code 1 l2 = l1, l2 += [4], all operations are l1, similar to pointers, referencing Shenma, if you don’t understand it, just think about it.
    Code 2 l2 = l1, l2 = l2 + [4], this is obviously a reassignment of l2. You can write l3 = l2 + [4], l2 += [4]. Then you will know the result.
    You can learn about python’s deep copy and shallow copy

    There is a very good answer in stackoverflow on the second floor. Just use id() to check the memory address

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

    Don’t worry too much, just look at the memory address and it will be clear at a glance.
    id is a built-in function of 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.)
    

    reply
    0
  • ringa_lee

    ringa_lee2017-04-17 13:50:00

    What I can think of is that some classes implement __iadd__ and behave differently from __add__. List's += is an example. Ordinary + will return a new list instance, while += is Directly manipulate the list itself.

    If you can confirm that i and x are two numbers, saying that i += x will cause problems is a bit nitpicking and dogmatism.

    reply
    0
  • 伊谢尔伦

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

    Mainly look at i, if i is an expression
    In i+=x, i is only calculated once
    i = i+x i needs to be calculated 2 times

    Then, if there are modification variables in the i expression, the values ​​of the two i in i = i+x may be different

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

    This example should be common in various grammar books

    reply
    0
  • 天蓬老师

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

    The above is for reference types, there should be no difference for value types.

    reply
    0
  • PHP中文网

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

    The core issue is to prevent side effects. Make your code behave consistently.

    reply
    0
  • 迷茫

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

    The poster here has some misunderstandings, i += x, this is a kind of syntax sugar, what does it really look like after expansion?
    In C language, the true form of i += x is i = i+x. Here i is reassigned, so the pointer address of i will change.
    But this is not the case in Python. The true form of i += x is i.extend(x), where the pointer address of i has not changed, only the value of i has been changed.

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

    reply
    0
  • 高洛峰

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

    What Floor 4 said is so right. There is a chance that the MD5 values ​​of two different files are the same. The question is, have you ever encountered them?

    reply
    0
  • Cancelreply