当前位置: 首页 > 面试题库 >

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

田永春
2023-03-14
问题内容

我有以下问题。

给定一个整数列表L,我需要生成所有子列表L[k:] for k in [0, len(L) - 1]而不生成副本

如何在Python中完成此操作?用某种缓冲对象?


问题答案:

简短的答案

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

长答案

测试可变和不变的值

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

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

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

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

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

使用视图节省内存

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

如果您确实想通过使用视图来节省内存,请考虑使用numpy数组。切片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:计算机工作量减少,程序员工作量增加!



 类似资料:
  • 问题内容: 给出清单 您可以使用诸如 但是,我想基于代码中其他位置设置的变量来执行此操作。我可以很容易地做到这一点 但是,我该如何为另一个做呢?我尝试用列表建立索引: 但这是行不通的。我也尝试过使用字符串: 但这也不起作用。 这可能吗? 问题答案: 那是为了: 与使用相同。

  • 问题内容: 我想编写一个确定子列表是否存在于较大列表中的函数。 有Python函数可以做到这一点吗? 问题答案: 如果您确定输入内容仅包含数字0和1,那么可以转换为字符串: 这样会创建两个字符串,因此它不是最有效的解决方案,但是由于它利用了Python中优化的字符串搜索算法,因此对于大多数用途而言可能已经足够好了。 如果效率非常重要,则可以查看适用于列表的Boyer- Moore 字符串搜索算法。

  • 问题内容: 我想在Python列表中切片每个字符串。 这是我当前的列表: 这是我想要的结果列表: 我想从列表中的每个字符串中切掉最后两个字符。 我怎样才能做到这一点? 问题答案: 使用列表推导创建一个新列表,并将表达式的结果应用于输入列表中的每个元素;这是最后两个字符的切片,返回其余部分: 演示:

  • 问题内容: 我目前正在尝试从发布请求响应中解析一些数据,并且不断收到此错误:“ TypeError:列表索引必须是整数或切片,而不是str” Python代码 JSON回应 我做了类似的代码,但这是一个get请求,一切都很好。 问题答案: 是一个数组,因此您不需要int,可以在after之后添加,它应该可以工作。然后,您可以在中引用对象内的键。

  • 我目前正试图解析get请求响应中的一些数据,但我一直遇到这样的错误:“TypeError:列表索引必须是整数或片,而不是str” 如果有人能帮我解决我想解决的问题,那就太好了。提前非常感谢你。

  • 问题内容: 我想要一种算法来遍历列表切片。切片大小在功能之外设置,可以不同。 在我看来,这就像: 有没有一种使用python 2.5正确定义的方法或其他方法? edit1:澄清 “分区”和“滑动窗口”这两个术语听起来都适用于我的任务,但是我不是专家。因此,我将更深入地解释该问题并添加到问题中: FatherList是我从文件中获取的一个多级numpy.array。函数必须找到序列的平均值(用户提供