栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Python中切片列表而不生成副本

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Python中切片列表而不生成副本

简短的答案

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

长答案

测试可变和不变的值

首先,让我们测试一下基本主张。我们可以证明,即使在整数之类的不可变对象的情况下,也仅复制了引用。这是三个不同的整数对象,每个都有相同的值:

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

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

id
s:

>>> map(id, a)[140502922988976, 140502922988952, 140502922988928]

对它们进行切片时,引用保持不变。尚未创建新对象:

>>> b = a[1:3]>>> map(id, b)[140502922988952, 140502922988928]

使用具有相同值的不同对象表明复制过程不会为interner困扰,它只是直接复制引用。

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

>>> 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: 0size: 72len: 1size: 80len: 2size: 88

正如Joe Pinsonault提醒我们的那样,开销加起来了。整数对象本身不是很大-
它们比引用大三倍。因此,这绝对可以为您节省一些内存,但是,渐近地,能够将多个“视图”列表放入同一内存可能会很好。

使用视图节省内存

不幸的是,Python没有提供简单的方法来产生作为列表“视图”的对象。也许我应该说“幸运”!这意味着您不必担心切片的来源;更改为原始图像不会影响切片。总的来说,这使得对程序行为的推理变得容易得多。

如果您确实想通过使用视图来节省内存,请考虑使用

numpy
数组。切片
numpy
数组时,切片和原始切片之间共享内存:

>>> a = numpy.arange(3)>>> aarray([0, 1, 2])>>> b = a[1:3]>>> barray([1, 2])

当我们修改

a
并再次查看时会发生什么
b

>>> a[2] = 1001>>> barray([   1, 1001])

但这意味着您必须确保在修改一个对象时,不要无意间修改了另一个对象。这是您使用时的折衷方案

numpy
:计算机工作量减少,程序员工作量增加!



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/647776.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号