python如何在赋值运算符后赋值

这个问题在这里已经有了答案:

  • 如何通过引用传递变量? 23个答案

  • 我以前遇到过这个问题,并且明白它会让人困惑。 这里有两个概念:

  • 一些数据结构是可变的,而另一些则不是
  • Python在大多数情况下都是关闭指针的
  • 所以让我们考虑一下列表的情况(当您使用ints时,您意外地发现了实习和窥视孔优化 - 我会在稍后讨论)

    所以让我们创建两个相同的列表(记住列表是可变的)

    In [42]: a = [1,2]
    
    In [43]: b = [1,2]
    
    In [44]: id(a) == id(b)
    Out[44]: False
    
    In [45]: a is b
    Out[45]: False
    

    尽管列表完全相同,但ab是不同的存储位置。 现在,这是因为python计算[1,2] ,将其分配给内存位置,然后调用该位置a (或b )。 这将需要相当长的时间蟒蛇检查每一个分配的内存位置,看是否[1,2]已经存在,分配b相同的内存位置作为a
    这并不是说列表是可变的,也就是说,您可以执行以下操作:

    In [46]: a = [1,2]
    
    In [47]: id(a)
    Out[47]: 4421968008
    
    In [48]: a.append(3)
    
    In [49]: a
    Out[49]: [1, 2, 3]
    
    In [50]: id(a)
    Out[50]: 4421968008
    

    看到了吗? 该值a持有已经改变,但内存位置也没有。 现在,如果将一堆其他变量名称分配给同一个内存位置呢? 他们也会改变,这将是一个语言的缺陷。 为了解决这个问题,python将不得不复制整个列表到一个新的内存位置,只是因为我想改变a

    即使是空列表也是如此:

    In [51]: a = []
    
    In [52]: b = []
    
    In [53]: a is b
    Out[53]: False
    
    In [54]: id(a) == id(b)
    Out[54]: False
    

    现在,让我们来谈谈关于指针的那些东西:

    假设您想要两个变量实际上谈论相同的内存位置。 然后,您可以将第二个变量分配给您的第一个变量:

    In [55]: a = [1,2,3,4]
    
    In [56]: b = a
    
    In [57]: id(a) == id(b)
    Out[57]: True
    
    In [58]: a is b
    Out[58]: True
    
    In [59]: a[0]
    Out[59]: 1
    
    In [60]: b[0]
    Out[60]: 1
    
    In [61]: a
    Out[61]: [1, 2, 3, 4]
    
    In [62]: b
    Out[62]: [1, 2, 3, 4]
    
    In [63]: a.append(5)
    
    In [64]: a
    Out[64]: [1, 2, 3, 4, 5]
    
    In [65]: b
    Out[65]: [1, 2, 3, 4, 5]
    
    In [66]: a is b
    Out[66]: True
    
    In [67]: id(a) == id(b)
    Out[67]: True
    
    In [68]: b.append(6)
    
    In [69]: a
    Out[69]: [1, 2, 3, 4, 5, 6]
    
    In [70]: b
    Out[70]: [1, 2, 3, 4, 5, 6]
    
    In [71]: a is b
    Out[71]: True
    
    In [72]: id(a) == id(b)
    Out[72]: True
    

    看看那里发生了什么! ab都被分配到相同的存储位置。 因此,您对其中一项的更改将反映在另一项上。

    最后,让我们简单地谈谈我之前提到的那种窥视孔的东西。 Python试图节省空间。 因此,它在启动时会将一些小内容加载到内存中(例如,小整数)。 因此,当你将一个变量赋给一个小整数(比如5 )时,python在将该值赋值给内存位置之前不必计算5 ,并且为它指定一个变量名(不同于你的名单)。 既然它已经知道什么是5 ,并且它已经隐藏在某个内存位置,它所做的只是为该内存位置分配一个变量名称。 但是,对于更大的整数,这不再是这种情况:

    In [73]: a = 5
    
    In [74]: b = 5
    
    In [75]: id(a) == id(b)
    Out[75]: True
    
    In [76]: a is b
    Out[76]: True
    
    In [77]: a = 1000000000
    
    In [78]: b = 1000000000
    
    In [79]: id(a) == id(b)
    Out[79]: False
    
    In [80]: a is b
    Out[80]: False
    

    这是python为小整数执行的优化。 一般来说,你不能指望a和c指向同一个位置。 如果你尝试用逐渐变大的整数进行这个实验,你会发现它在某个时刻停止工作。 我敢肯定,1000人足够大,但我不在电脑附近; 我以为我记得它是从-128到127的所有整数都以这种方式处理(或其他“整数”)。


    你的理解通常是正确的,但值得注意的是,Python列表与C或C ++中的数组相比是完全不同的动物。 从文档:

    id(obj)返回一个对象的“身份”。 这是一个整数(或长整数),在整个生命周期中保证这个对象是唯一的并且是常量。 具有非重叠生命周期的两个对象可能具有相同的id()值。

    你的问题的简单答案是,Python中的列表实际上是引用。 这导致它们的存储器地址不同,因为地址是参考地址,而不是人们可能期望的那样。

    链接地址: http://www.djcxy.com/p/20835.html

    上一篇: How does python assign values after assignment operator

    下一篇: Modify parameter as a side