1
limbo0 2015-01-05 16:37:26 +08:00
浅拷贝是会变吧,深拷贝不会变
没见过切片引用的~~ |
2
fdb713 2015-01-05 16:39:25 +08:00
直接
a[1:2] = [5] 不就可以达到 a == [1,2,3,4,5]的效果了么。。。 |
3
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] 了 |
4
hahastudio 2015-01-05 17:13:51 +08:00 1
先说一下,很多人可能会误解,实际 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] |
5
ryanking8215 OP @hahastudio 谢谢,明白了
|
6
ruoyu0088 2015-01-05 18:42:37 +08:00
有啊,NumPy的数组。
|
7
yegle 2015-01-07 05:32:15 +08:00
slice是复制不是引用也不一定是坏事…写Golang经常没转过弯来…
至于想做切片引用…写个class包装一下不就好了…为什么一定要语言内置呢… https://gist.github.com/yegle/af51f08ef289bdffbc7f |
8
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] [] |
9
yegle 2015-01-07 14:46:02 +08:00 1
@hahastudio 我在3.4上测试的,更新了gist你可以参考下。
和你的代码里不同的一点是,Python里assignment是没有magic method可以用来重载的,所以你的代码里foo函数对ref_l进行赋值是不会修改原list的,只能用ref_l[:] = [999]的方式进行修改。 所谓的『引用类型』就是一个普通list基础上对start/stop range进行操作而已…这个和Golang里的slice(变长数组)实现上是一样的。 |
10
yegle 2015-01-07 14:46:47 +08:00
__setitem__可能还需要修改,我懒得做了,明白意思就好了。
|