问题:分配如何与Python列表切片一起使用?

Python文档说切片列表会返回一个新列表。
现在,如果返回了“新”列表,我将对“分配给切片”存在以下疑问

a = [1, 2, 3]
a[0:2] = [4, 5]
print a

现在的输出将是:

[4, 5, 3] 
  1. 返回内容的内容如何出现在表达式的左侧?
  2. 是的,我阅读了文档,并说有可能,因为切片列表会返回“新”列表,为什么要修改原始列表?我无法理解其背后的机制。

Python doc says that slicing a list returns a new list.
Now if a “new” list is being returned I’ve the following questions related to “Assignment to slices”

a = [1, 2, 3]
a[0:2] = [4, 5]
print a

Now the output would be:

[4, 5, 3] 
  1. How can something that is returning something come on the left side of expression?
  2. Yes, I read the docs and it says it is possible, now since slicing a list returns a “new” list, why is the original list being modified? I am not able to understand the mechanics behind it.

回答 0

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

1)切片:

b = a[0:2]

这将复制的切片a并将其分配给b

2)切片分配:

a[0:2] = b

这会用的内容替换的切片。ab

尽管语法相似(我想是通过设计实现的!),但这是两个不同的操作。

You are confusing two distinct operation that use very similar syntax:

1) slicing:

b = a[0:2]

This makes a copy of the slice of a and assigns it to b.

2) slice assignment:

a[0:2] = b

This replaces the slice of a with the contents of b.

Although the syntax is similar (I imagine by design!), these are two different operations.


回答 1

当您a=运算符的左侧指定时,您使用的是Python的常规分配,该分配会更改a当前上下文中的名称以指向新值。这不会更改以前a指向的值。

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

插入

>>> a = [1, 2, 3]
>>> a[0:0] = [-3, -2, -1, 0]
>>> a
[-3, -2, -1, 0, 1, 2, 3]

删除

>>> a
[-3, -2, -1, 0, 1, 2, 3]
>>> a[2:4] = []
>>> a
[-3, -2, 1, 2, 3]

更换

>>> a
[-3, -2, 1, 2, 3]
>>> a[:] = [1, 2, 3]
>>> a
[1, 2, 3]

注意:

切片的长度可以与分配序列的长度不同,从而在目标序列允许的情况下更改目标序列的长度。- 来源

切片分配提供类似于元组拆包的功能。例如,a[0:1] = [4, 5]等效于:

# Tuple Unpacking
a[0], a[1] = [4, 5]

使用元组拆包,您可以修改非顺序列表:

>>> a
[4, 5, 3]
>>> a[-1], a[0] = [7, 3]
>>> a
[3, 5, 7]

但是,元组拆包仅限于替换,因为您不能插入或删除元素。

在所有这些操作之前和之后,a是相同的确切列表。Python只是提供了不错的语法糖来就地修改列表。

When you specify a on the left side of the = operator, you are using Python’s normal assignment, which changes the name a in the current context to point to the new value. This does not change the previous value to which a was pointing.

By specifying a[0:2] on the left side of the = operator, you are telling Python you want to use Slice Assignment. Slice Assignment is a special syntax for lists, where you can insert, delete, or replace contents from a list:

Insertion:

>>> a = [1, 2, 3]
>>> a[0:0] = [-3, -2, -1, 0]
>>> a
[-3, -2, -1, 0, 1, 2, 3]

Deletion:

>>> a
[-3, -2, -1, 0, 1, 2, 3]
>>> a[2:4] = []
>>> a
[-3, -2, 1, 2, 3]

Replacement:

>>> a
[-3, -2, 1, 2, 3]
>>> a[:] = [1, 2, 3]
>>> a
[1, 2, 3]

Note:

The length of the slice may be different from the length of the assigned sequence, thus changing the length of the target sequence, if the target sequence allows it. – source

Slice Assignment provides similar function to Tuple Unpacking. For example, a[0:1] = [4, 5] is equivalent to:

# Tuple Unpacking
a[0], a[1] = [4, 5]

With Tuple Unpacking, you can modify non-sequential lists:

>>> a
[4, 5, 3]
>>> a[-1], a[0] = [7, 3]
>>> a
[3, 5, 7]

However, tuple unpacking is limited to replacement, as you cannot insert or remove elements.

Before and after all these operations, a is the same exact list. Python simply provides nice syntactic sugar to modify a list in-place.


回答 2

我之前碰到过同样的问题,它与语言规范有关。根据分配陈述

  1. 如果分配的左侧是subscription,则Python将调用该对象。a[i] = x等价于a.__setitem__(i, x)

  2. 如果赋值的左边是slice,Python也将调用__setitem__,但是使用不同的参数: a[1:4]=[1,2,3]等于 a.__setitem__(slice(1,4,None), [1,2,3])

因此,“ =”左侧的列表切片的行为有所不同。

I came across the same question before and it’s related to the language specification. According to assignment-statements,

  1. If the left side of assignment is subscription, Python will call on that object. a[i] = x is equivalent to a.__setitem__(i, x).

  2. If the left side of assignment is slice, Python will also call __setitem__, but with different arguments: a[1:4]=[1,2,3] is equivalent to a.__setitem__(slice(1,4,None), [1,2,3])

That’s why list slice on the left side of ‘=’ behaves differently.


回答 3

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

By slicing on the left hand side of an assignment operation, you are specifying which items to assign to.


声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。