python创建独立副本_在Python中创建列表而不生成副本

简短的答案

切片列表不会生成列表中对象的副本;它只是复制对它们的引用。这是问题的答案。

长的答案

测试可变和不可变值

首先,让我们来测试基本的索赔。我们可以显示即使在不可变对象(如整数)的情况下,仅复制引用。这里有三个不同的整数对象,每个对象具有相同的值:

>>> a = [1000 + 1, 1000 + 1, 1000 + 1]

它们具有相同的值,但是您可以看到它们是三个不同的对象,因为它们具有不同的ids:

>>> map(id, a)

[140502922988976, 140502922988952, 140502922988928]

当您切片时,参考文献保持不变。没有创建新对象:

>>> b = a[1:3]

>>> map(id, b)

[140502922988952, 140502922988928]

使用具有相同值的不同对象表明复制过程不会使用interning – 它只是直接复制引用。

使用可变值进行测试可获得相同的结果:

>>> a = [{0: 'zero', 1: 'one'}, ['foo', 'bar']]

>>> map(id, a)

[4380777000, 4380712040]

>>> map(id, a[1:]

... )

[4380712040]

检查剩余的内存开销

当然,这些引用本身就被复制了。每个在64位机器上花费8个字节。每个列表都有自己的72个字节的内存开销:

>>> for i in range(len(a)):

... x = a[:i]

... print('len: {}'.format(len(x)))

... print('size: {}'.format(sys.getsizeof(x)))

...

len: 0

size: 72

len: 1

size: 80

len: 2

size: 88

正如Joe Pinsonault reminds us那样,这个开销就增加了。整数对象本身不是很大 – 它们比引用的大三倍。所以这样可以在绝对意义上节省一些记忆,但渐近地,可以将多个列表作为“视图”列入同一个内存可能是很好的。

通过使用视图节省内存

不幸的是,Python不提供简单的方法来生成列表中的“视图”对象。或者我应该说“幸运”!这意味着你不用担心切片来自哪里;改变原来不会影响切片。总体来说,这使得程序的行为更容易理解。

如果您真的想通过使用视图来节省内存,请考虑使用numpy数组。当切片数组时,内存在切片和原始文件之间共享:

>>> a = numpy.arange(3)

>>> a

array([0, 1, 2])

>>> b = a[1:3]

>>> b

array([1, 2])

当我们修改a并再次查看b时会发生什么?

>>> a[2] = 1001

>>> b

array([ 1, 1001])

但这意味着您必须确保在修改一个对象时,您不会无意中修改另一个对象。当您使用numpy时,这是权衡:计算机工作少,程序员工作更多!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值