赋值如何与python list slice一起使用

Kar*_*and 83 python list slice

Python doc说切片列表会返回一个新列表.现在,如果返回"新"列表,我有以下与"分配给切片"有关的疑问

a = [1, 2, 3]
a[0:2] = [4, 5]
print a
Run Code Online (Sandbox Code Playgroud)

现在输出将是:

[4, 5, 3] 
Run Code Online (Sandbox Code Playgroud)
  1. 如何能够回归的东西出现在表达的左侧.
  2. 是的,我阅读了文档并且它说它是可能的,因为切片列表返回一个"新"列表,为什么原始列表被修改,我无法理解它背后的机制.

NPE*_*NPE 96

您使用非常相似的语法混淆了两个不同的操作:

1)切片:

b = a[0:2]
Run Code Online (Sandbox Code Playgroud)

这会生成切片的副本a并将其分配给b.

2)切片分配:

a[0:2] = b
Run Code Online (Sandbox Code Playgroud)

取代了切片a的内容b.

虽然语法类似(我想象设计!),但这些是两种不同的操作.

  • @KartikAnand因为它不是.这不是语言指定的内容. (10认同)
  • 这就是我的疑问,在第二种情况下,为什么不是一个新的列表? (4认同)
  • @KartikAnand:基本上是的。解释器知道哪个是哪个,并适当地处理它们。 (2认同)
  • @Dubslow:您可以使用 [itertools](https://docs.python.org/2/library/itertools.html) 模块来做到这一点。对于您的情况,请使用函数 [islice](https://docs.python.org/2/library/itertools.html#itertools.islice),使用 `start=1`、`stop=None`。这将避免任何副本并使用延迟评估(在您的情况下延迟访问原始列表)。 (2认同)

Cas*_*all 54

当您a=运算符的左侧指定时,您正在使用Python的常规赋值,它会更改a当前上下文中的名称以指向新值.这不会更改a指向的先前值.

通过a[0:2]=运算符的左侧指定,您告诉Python您要使用切片分配.切片分配是列表的特殊语法,您可以在其中插入,删除或替换列表中的内容:

插入:

>>> a = [1, 2, 3]
>>> a[0:0] = [-3, -2, -1, 0]
>>> a
[-3, -2, -1, 0, 1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

删除:

>>> a
[-3, -2, -1, 0, 1, 2, 3]
>>> a[2:4] = []
>>> a
[-3, -2, 1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

更换:

>>> a
[-3, -2, 1, 2, 3]
>>> a[:] = [1, 2, 3]
>>> a
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)

注意:

切片的长度可以与指定序列的长度不同,因此如果靶序列允许,则改变靶序列的长度.- 来源

Slice Assignment提供与Tuple Unpacking类似的功能.例如,a[0:1] = [4, 5]相当于:

# Tuple Unpacking
a[0], a[1] = [4, 5]
Run Code Online (Sandbox Code Playgroud)

使用Tuple Unpacking,您可以修改非顺序列表:

>>> a
[4, 5, 3]
>>> a[-1], a[0] = [7, 3]
>>> a
[3, 5, 7]
Run Code Online (Sandbox Code Playgroud)

但是,元组解包仅限于替换,因为您无法插入或删除元素.

在所有这些操作之前和之后,a是完全相同的列表.Python只是提供了很好的语法糖来就地修改列表.

  • 相似但不完全相同,因为左右可以有不等数量的元素. (6认同)
  • 是[a [:] = some_list`等同于`a = some_list [:]`还是`a = some_list`? (2认同)
  • @ jadkik94都不是。a [:] = some_list`将a的每个元素设置为some_list的元素。不管您提到哪一个,都会改变a的含义。例如:a = [1、2、3]`b = a`a [:] = [4、5、6]`a是b`。如果最后一行更改了`a`的值,而不是对其进行了更改,则它将为False。 (2认同)

Sta*_*tan 19

我之前遇到过同样的问题,它与语言规范有关.根据作业陈述,

  1. 如果赋值的左侧是subscription,则Python将调用__setitem__该对象.a[i] = x相当于a.__setitem__(i, x).

  2. 如果赋值的左侧是切片,Python也会调用__setitem__,但是使用不同的参数: a[1:4]=[1,2,3]相当于 a.__setitem__(slice(1,4,None), [1,2,3])

这就是为什么'='左侧的列表切片表现不同的原因.


fra*_*xel 5

通过在赋值操作的左侧切片,您可以指定要分配给哪些项目。