分配如何与列表切片一起使用? [重复]

问题描述 投票:0回答:5

Python 文档说切片列表会返回一个新列表。
现在,如果返回“新”列表,我有以下与“分配给切片”相关的问题

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

现在输出将是:

[4, 5, 3] 
  1. 返回东西的东西怎么会出现在表达式的左边?
  2. 是的,我阅读了文档,它说这是可能的,既然切片列表返回一个“新”列表,为什么要修改原始列表?我无法理解它背后的机制。
python list slice
5个回答
153
投票

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

1)切片:

b = a[0:2]

这会复制

a
的切片并将其分配给
b
.

2)切片分配:

a[0:2] = b

这个a

的内容替换
b
的切片。

虽然语法相似(我想是设计出来的!),但这是两种不同的操作。


90
投票

当您在

a
运算符的左侧指定
=
时,您正在使用 Python 的 normal assignment,它将当前上下文中的名称
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]

注:

切片的长度可能与切片的长度不同 分配的序列,从而改变目标序列的长度,如果 目标序列允许它。 - 来源

Slice assignment 提供与 tuple unpacking 类似的功能。例如,

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 只是提供了很好的语法糖来就地修改列表。


35
投票

我之前遇到过同样的问题,它与语言规范有关。根据赋值语句

  1. 如果赋值的左侧是订阅,Python 将对该对象调用

    __setitem__
    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])

这就是为什么“=”左侧的列表切片表现不同的原因。


5
投票

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


2
投票

当您执行

a[0:2] = [4,5]
时,您为
=
(切片
a[0:2]
)的左侧分配了
=
右侧的值,
[4,5]
.

© www.soinside.com 2019 - 2024. All rights reserved.