cst*_*ur4 7 python list python-2.7
>>>a = [3, 2]
>>>a[0:1][0] = 1
>>>a
[3, 2]
>>>a[0:1] = [1]
>>>a
[1, 2]
Run Code Online (Sandbox Code Playgroud)
什么a[0:1]意思?
a[0:1][0] = 1应该改变a的值.a[0:1] = [1]不应该改变a的值.我认为两者的结果彼此不一致.你能帮我解决一下这个问题吗?
切片列表会创建一个浅表副本 - 它不是对原始副本的引用.所以,当你得到那个切片时,它不会与原始切片绑定list a.因此,您可以尝试更改它的单个元素,但它不会存储在变量中,也不会对任何原始元素进行更改list.
澄清一下,前者对你做__getitem__- 访问部分列表(副本):
a[0:1][0] = 1
Run Code Online (Sandbox Code Playgroud)
您正在编辑切片[0:1],这是一个唯一的浅表副本a,因此不会编辑a自己.
但是对于后者,一个是调用__setitem__,当然会就地编辑对象:
a[0:1] = [1]
Run Code Online (Sandbox Code Playgroud)
您直接参考和编辑部分内容a,因此会实时更改.
在内部,这是一个很大的区别:
>>>a = [3, 2]
>>>a[0:1][0] = 1
Run Code Online (Sandbox Code Playgroud)
是一个简写
temp = a[0:1]
temp[0] = 1
Run Code Online (Sandbox Code Playgroud)
并在内部表示为
a.__getitem__(slice(0, 1)).__setitem__(0, 1)
Run Code Online (Sandbox Code Playgroud)
RESP.
temp = a.__getitem__(slice(0, 1))
temp.__setitem__(0, 1)
Run Code Online (Sandbox Code Playgroud)
所以它访问列表的一部分,创建一个单独的对象,并对该对象进行赋值,然后将其删除.
OTOH,
>>>a[0:1] = [1]
Run Code Online (Sandbox Code Playgroud)
不
a.__setitem__(slice(0, 1), [1])
Run Code Online (Sandbox Code Playgroud)
它只对原始对象进行操作.
因此,虽然看起来很相似,但这些表达方式与它们的含义截然不同.
让我们测试一下:
class Itemtest(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
def __setitem__(self, item, value):
print "__setitem__", self, item, value
def __getitem__(self, item):
print "__getitem__", self, item
return Itemtest("inner")
a = Itemtest("outer")
a[0:1] = [4]
temp = a[0:1]
temp[0] = 4
a[0:1][0] = 4
Run Code Online (Sandbox Code Playgroud)
输出
__setitem__ outer slice(0, 1, None) [4]
__getitem__ outer slice(0, 1, None)
__setitem__ inner 0 4
__getitem__ outer slice(0, 1, None)
__setitem__ inner 0 4
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
869 次 |
| 最近记录: |