使用Python进行多重切片分配

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

我正在阅读一篇名为“复制列表中的每个成员”的文章。我找到了解决这个我无法理解的问题的答案:

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

你能一步步解释一下下面这行程序是如何工作的吗:

>>> a[:0] = a[::2] = a[1::2] = a[:]
python python-3.x slice
1个回答
3
投票

这里的关键是理解序列 是从左到右执行的,全部参考最右边的值。

最右边的切片

a[:]
被分配给最左边 3 个切片中的每一个。请注意使用
a[:]
而不是
a
,这确保我们在开始时制作一个副本,并且我们对
a
的操作不会更改此值。更清晰的写法是存储副本
a[:]
:

>>> a = [3, 1, 4, 1, 5]
>>> b = a[:]
>>> b
[3, 1, 4, 1, 5]

>>> a[:0] = b
>>> a
[3, 1, 4, 1, 5, 3, 1, 4, 1, 5]
#^^^^^^^^^^^^^ changed

>>> a[::2] = b
>>> a
[3, 1, 1, 1, 4, 3, 1, 4, 5, 5]
#^     ^     ^     ^     ^ changed 

>>> a[1::2] = b
>>> a
[3, 3, 1, 1, 4, 4, 1, 1, 5, 5]
#   ^     ^     ^     ^     ^ changed

让我们讨论各个步骤

  1. b = a[:]
    制作 a 的临时副本
  2. a[:0] = b
     在前面插入 
    b
    ,但实际上只是用于将 a 填充到两倍长度,以便接下来的两条语句起作用
  3. a[::2] = b
     将值设置为偶数索引(即从前面开始的每隔一个索引)
  4. a[1::2] = b
     将值设置为奇数索引(即除前面之外的每隔一个索引)

获得相同结果的另一种方法是以下元组分配,它也首先评估右侧,然后从左到右评估左侧:

(a[:0], a[::2], a[1::2]) = (a[:], a[:], a[:])
    
© www.soinside.com 2019 - 2024. All rights reserved.