python 有切片引用类型吗?

2015-01-05 16:30:24 +08:00
 ryanking8215
a=[1,2,3,4,5]
b=a[1:2]
b[0] = 5 # b是a[1:2]切片的浅拷贝,a的值不变

有没有切片引用类型呢?
比如nodejs:
buf = buf.slice(offset)
3586 次点击
所在节点    Python
10 条回复
limbo0
2015-01-05 16:37:26 +08:00
浅拷贝是会变吧,深拷贝不会变

没见过切片引用的~~
fdb713
2015-01-05 16:39:25 +08:00
直接
a[1:2] = [5]
不就可以达到
a == [1,2,3,4,5]的效果了么。。。
fdb713
2015-01-05 16:41:03 +08:00
@fdb713 打错了 a == [1, 5, 3, 4, 5]
你甚至可以
a=[1,2,3,4,5,6,7]
a[::2] = [2,4,6,8]

a就直接为 [2, 2, 4, 4, 6, 6, 8] 了
hahastudio
2015-01-05 17:13:51 +08:00
先说一下,很多人可能会误解,实际 Python 的运行效果是这样的:
>>> a = [1,2,3,4,5]
>>> b = a[1:2]
>>> b
[2]
>>> b[0]=5
>>> b
[5]
>>> a
[1, 2, 3, 4, 5]

很遗憾,Python 的序列切片一定是复制的,所以实际没有切片引用类型
这也就是为什么会有一个深度复制 list 的 trick 是 b = a[:]

你想要的效果只能迂回地获得。

如果你知道 a[1:2] 其实是 a[slice(1,2)] 的话
你可以传两个参数,就像是当初 C++ 传数组似的:

def foo(array, slc):
....array[slc] = [5]

>>> foo(a, slice(1,2))
>>> a
[1, 5, 3, 4, 5]
ryanking8215
2015-01-05 17:40:54 +08:00
@hahastudio 谢谢,明白了
ruoyu0088
2015-01-05 18:42:37 +08:00
有啊,NumPy的数组。
yegle
2015-01-07 05:32:15 +08:00
slice是复制不是引用也不一定是坏事…写Golang经常没转过弯来…

至于想做切片引用…写个class包装一下不就好了…为什么一定要语言内置呢…

https://gist.github.com/yegle/af51f08ef289bdffbc7f
hahastudio
2015-01-07 11:21:03 +08:00
@yegle 大大我们的 Python 是不是不在同一个位面上= =

我用的是 2.7.8,其实您这个方案跟普通的是没有区别的= =
>>> l = [1, 2, 3, 4]
>>> l[0] = 999
>>> l
[999, 2, 3, 4]
>>> l = [1, 2, 3, 4]
>>> ref_copy = MyList(l)
>>> def foo(ref_l):
....ref_l = [999]

>>> foo(ref_copy[0])
>>> l
[1, 2, 3, 4]

然后 2.7.8 并没有抛弃 __getslice__ 和 __setslice__
>>> ref_copy[1:3]
[]
yegle
2015-01-07 14:46:02 +08:00
@hahastudio 我在3.4上测试的,更新了gist你可以参考下。

和你的代码里不同的一点是,Python里assignment是没有magic method可以用来重载的,所以你的代码里foo函数对ref_l进行赋值是不会修改原list的,只能用ref_l[:] = [999]的方式进行修改。

所谓的『引用类型』就是一个普通list基础上对start/stop range进行操作而已…这个和Golang里的slice(变长数组)实现上是一样的。
yegle
2015-01-07 14:46:47 +08:00
__setitem__可能还需要修改,我懒得做了,明白意思就好了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/159413

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX