zoukankan      html  css  js  c++  java
  • python易错盲点排查之+=与+的区别分析以及一些赋值运算踩过的坑

    问题1. int和list是不一样的

    >>> a=1
    >>> b=a
    >>> a+=1
    >>> a,b
    (2, 1)
    >>> a=[1,2,3,4]
    >>> b=a
    >>> a+=[5]
    >>> a,b
    ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])

    通俗地讲,类型为int时,a和b是“不一样的”;类型为list时,a和b是“一样的”。术语叫做immutable和mutable,具体原理在这个节点不必深究。
    问题1.1. 我们通常运行b=a这一语句时,会直觉地认为,b和a已经不一样了。

    >>> a=[[1],[2],[3],[4]]
    >>> b+=a[0:2]
    >>> b
    [1, 2, 3, 4, [1], [2]]
    >>> a=[[1],[2],[3],[4]]
    >>> b=[]
    >>> b+=a[0:2]
    >>> a,b
    ([[1], [2], [3], [4]], [[1], [2]])
    >>> b[0]
    [1]
    >>> b[0][0]='changed!'
    >>> # You don't expect a to change
    >>> # However
    >>> a, b
    ([['changed!'], [2], [3], [4]], [['changed!'], [2]])

    可以看到,a[0]的[1]和b[0]的[1]是“一样的”,因为改变b[0]就会改变a[0](注意不是改变b,是改变b[0]。改变b不会对a有任何影响)
    问题2. list的情况下,a+=b和a=a+b是不一样的

    >>> a=[1,2,3,4]
    >>> b=a
    >>> a+=[5]
    >>> a,b
    ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
    >>> a=[1,2,3,4]
    >>> b=a
    >>> a=a+[5]
    >>> a,b
    ([1, 2, 3, 4, 5], [1, 2, 3, 4])

    同样通俗地讲,在+=的情况下,a还是原来的a,和b“一样”;在+的情况下,a已经不是原来的a了,和b“不一样”。
    问题3. 如果要让+=和+行为一致,应该怎么做?

    >>> import copy
    >>> a=[1,2,3,4]
    >>> b=copy.deepcopy(a)
    >>> a+=[5]
    >>> a,b
    ([1, 2, 3, 4, 5], [1, 2, 3, 4])

    这与问题2中a=a+b的情况结果一致了。当对list进行b=a时,实际上进行的是“引用”操作;只有使用b=copy.deepcopy(a)才是进行我们通常期望的“拷贝”操作。
    问题4. 回到问题中的代码,当k=1时,以下代码:

    subset += (elements[0:size])

    根据问题1.1,subset与elements是“一样的”,因此未来改变subset的元素的操作有可能改变elements的元素

    到这行代码时,注意set就是递归传递过来的subset:

    #set[j] +=  (elements[i])  #Why Elements change here?
    set[j]  = set[j] +  (elements[i]) 

    根据问题2,+=中set[j]依然是原来的set[j],也就可能是elements的元素。因此

    set[j] += elements[i]

    可能会等价于

    elements[*] += elements[i]

    一旦改变了elements的元素,结果自然就不对了。
    怎么解决这个问题?根据问题3,只要保证set与elements是“不一样的”,就符合程序的逻辑。因此将

    subset += (elements[0:size])

    改为(记得import copy)

    subset += copy.deepcopy(elements[0:size])

    就能在+=的情况下正常运行了。
    总结:在python中,list类型的赋值b=a进行的引用操作,而非拷贝操作,在需要拷贝操作时,需要加上b=copy.deepcopy(a)。(copy.copy和copy.deepcopy的区别超出问题范畴,有兴趣可以google)

  • 相关阅读:
    xlib dev[1]
    [转]Kinect for Windows SDK开发入门(三):基础知识 下
    [译]Kinect for Windows SDK开发入门(六):骨骼追踪基础 上
    [转]Kinect for Windows SDK开发入门(七):骨骼追踪基础 下
    [转]Kinect for Windows SDK开发入门(一):开发环境配置
    [转]Kinect for Windows SDK开发入门(四):景深数据处理 上
    [转]Kinect for Windows SDK开发入门(二):基础知识 上
    [转]Kinect for Windows SDK开发入门(五):景深数据处理 下
    Ogre/Torque 基础类plane简单释疑
    torque dts格式大概分析
  • 原文地址:https://www.cnblogs.com/ECJTUACM-873284962/p/8530459.html
Copyright © 2011-2022 走看看