찾다

 >  Q&A  >  본문

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

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

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

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

迷茫迷茫2784일 전782

모든 응답(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
  • 취소회신하다