【问题标题】:Trying to understand slices of lists [duplicate]试图理解列表的切片[重复]
【发布时间】:2018-04-17 16:14:11
【问题描述】:

我有一个列表,我想了解其中的一部分。我截取了[0:1] 的一部分:

>>> l=[1,2,3,4]
>>> id(l[0])
140079803522784
>>> id(l[0:1][0])
140079803522784

它们是一样的。但是:

>>> l[0]=7
>>> l
[7, 2, 3, 4]
>>> l[0:1][0]=13
>>> l
[7, 2, 3, 4]

所以 slice 的 0-element 和 list 的 0-element 是一样的,但是当我在 slice 中改变它时,它在列表中并没有改变。为什么不呢?

【问题讨论】:

  • 切片创建浅副本...
  • 因为切片会生成一个新列表。
  • 现在尝试使用任意对象(例如自定义类)而不是整数(不可变)来做同样的事情。你会大吃一惊的。
  • @DeepSpace 我做到了。同样的事情: >>>l=[[1,2],[1,3]] >>> l[0:1][0]=[7] >>> l [[1, 2], [1 , 3]]
  • 在你的第一个例子中,l[0]l[0:1][0] 只不过是l 的元素,特别是它们是第一个元素,即数字1。它们与原始列表没有关联。

标签: python


【解决方案1】:

From the documentation:

所有切片操作都会返回一个包含请求元素的新列表。这意味着以下切片返回列表的新(浅)副本。

所以基本上当您执行l[0:1][0] = 13 时,您将分配13 作为新列表中的值,而不是l。就像你做的一样

[l[0]] = 13

g = [l[0]]
g[0] = 13

请注意,这仅适用于不可变类型,例如 intstr。由于切片执行的是浅拷贝,因此如果您修改对象,您将获得预期的行为。

>>> l = [{'hi': 7}, {}, {}, {}]
[{'hi': 7}, {}, {}, {}]
>>> l[0:1][0]['hi'] = 1
>>> l[0]
{'hi': 1}

【讨论】:

  • 是副本,是的,但是副本中的元素引用的元素与原始列表相同。另外,如果我做l[0:1]=[13]l 就会改变。
  • @ericj 确实如此,但整数是不可变的。您的第二个示例是显式切片分配,当然 l 会更改。
  • @jonrsharpe 好吧,我尝试了可变列表:l=[[1,2],[1,3]];l[0:1][0]=[7]。那么l 就是[[1, 2], [1, 3]]
  • 那个例子是 not 切片分配。它通过索引分配到切片的 result 中,实际上是m = l[0:1]; m[0] = [7]。仅当 last 索引是切片时才进行切片分配。
  • 啊,现在我明白了。 l[0:1] 是另一个列表。它的第一个元素等于l 的第一个元素,但我没有修改那个元素。我替换了它,所以我更改了l[0:1] 列表。谢谢。
猜你喜欢
  • 1970-01-01
  • 2015-05-09
  • 2015-03-18
  • 1970-01-01
  • 2021-09-07
  • 2023-03-28
  • 2020-12-19
  • 2019-07-17
  • 1970-01-01
相关资源
最近更新 更多