![](/img/trans.png)
[英]Why does python list slicing allow for referencing entries that aren't there?
[英]Integer and referencing on python list slicing
谁能解释以下列表参考问题? 我不清楚。
例如 :
>>> a = [1,2,3,4]
>>> a[0:2] = 11,22
>>> a
[11, 22, 3, 4]
>>> b = a[0:2]
>>> b[0:2] = 33,44
>>> b
[33, 44]
>>> a
[11, 22, 3, 4]
为什么a[0:2] = 11,22
更改列表a
而b[0:2] = 33,44
没有更改列表? b
不是引用a[0:2]
吗? 为什么列表的引用会更改其值,但整数引用却不会更改?
例:
>>> a = 1
>>> b = a
>>> a = 2
>>> b
1
我认为这是不言而喻的。
>>> a = [1,2,3,4]
>>> a[0:2] = 11,22
>>> a
[11, 22, 3, 4]
您正在a的索引0
和1
处修改值。 因此,索引2
和3
原始值保持不变。
>>> b = a[0:2]
>>> b[0:2] = 33,44
>>> b
[33, 44]
>>> a
[11, 22, 3, 4]
您已将索引0
和1
处的值从a
复制到b
,因此b
只有2个值。 然后,用[33,44]
覆盖b
的值。 因此,您所观察到的结果。
有些数据类型是不可变的(值不能更改),例如数字,字符串,元组。 dict,list等数据类型是可变的(值可以更改)
插图
>>> a = [1,2,3,4]
>>> b = a
>>> id(a)
46734952
>>> id(b)
46734952
>>> b[1] = 8
>>> print(b)
[1, 8, 3, 4]
>>> print(a)
[1, 8, 3, 4]
在上述情况下, b
是一个参考a
。 即, a
和b
都指向同一列表。 对b
所做的任何更改也会影响a
。 可以使用id
函数进行验证。 相同的id
值表示两者都指向同一对象。
>>> c = a[:]
>>> print(c)
[1, 8, 3, 4]
>>> id(a)
46734952
>>> id(c)
46563240
在上述情况下,将a
切片分配给c
。 因此,将制作一个副本并将其分配给c
。 因此, a
和c
的id
值是不同的。
因为有两种类型的数据
可变数据类型
不变的数据类型
更改mutable type
将更改它的对象;当更改immutable type
时,将创建新的对象,然后将其分配给变量
我将逐步回答:
a[0:2] = 11,22
与执行a[0] = 11; a[1] = 22
a[0] = 11; a[1] = 22
。 这是常规任务,在这里不足为奇。 当您这样做时:
b = a[0:2]
您会得到列表的浅表副本 。 这意味着您将获得一个新列表,其中包含对每个对象的引用。 由于在您的情况下,列表中填充有int
,因此它实际上也是一个副本。 但是,请考虑以下示例:
让我们定义一个类,它包装一个int
(或任何其他数据类型,它是python :)),但是是可变的。
In [41]: class num(object):
...: def __init__(self, x):
...: self.x = x
...:
现在,仅在我们的课程中定义a
In [42]: a = [num(x) for x in range(1,5)]
In [43]: a[0].x
Out[43]: 1
In [44]: a[1].x
Out[44]: 2
现在,我们将指定的片a
成b
。 与您的示例相反,当列表包含数字值时,此处包含引用,因此可以说它们是相同的:
In [45]: b = a[0:2]
In [46]: b[0].x
Out[46]: 1
In [47]: b[1].x
Out[47]: 2
因此,当我在b
更改一个时:
In [48]: b[0].x = 3
它反映了a
:
In [50]: a[0].x
Out[50]: 3
但这是一个不同的列表。 因此,将新实例分配给列表中的位置...
In [49]: b[1] = num(20)
...是不是体现在a
:
In [51]: a[1].x
Out[51]: 2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.