L = [0, 1, 2]
L[::2], *rest = "abcdef"
print(L, rest)
预期输出:
['a', 1, 'b'] ['c', 'd', 'e', 'f']
实际输出:
ValueError: attempt to assign sequence of size 1 to extended slice of size 2
由于某些原因,无法将拆包分配与扩展切片分配结合使用吗?为什么?我没有在PEP 3132 -- Extended Iterable Unpacking或Python数据模型中看到任何明显的迹象表明这应该是无效的。
答案 0 :(得分:6)
这不是错误。当有多个左手表达式时,总是通过将右可迭代项中的每一项映射到对应的逗号分隔的左手表达式来完成解压缩。您的示例中的L[::2]
表达式只是两个左手表达式之一,因此从拆开右手可迭代对象的包装中仅收到一项,而加星号的左手表达式则接收其余内容。
PEP-3132的基本原理指出:
许多算法要求将序列分成“第一对休息”对。 使用新语法,
first, rest = seq[0], seq[1:]
被更清洁,效率更高的取代:
first, *rest = seq
您的
L[::2], *rest = "abcdef"
因此等效于:
L[::2], rest = "a", "bcdef"
由于ValueError: attempt to assign sequence of size 1 to extended slice of size 2
无法为2的切片进一步拆包,因此将导致上述错误"a"
。
如果Python将对解压缩的解释添加到语法中,则它可以例如声明以下内容:
L[::2], *rest = "ab", "c", "d"
含糊不清-应该将L
变成["a", 1, "b"]
和rest
变成["c", "d"]
,还是应该将L
变成["ab", 1, "c"]
和{{1} }成为rest
?始终在每个LHS表达式的可迭代项中分配一项,使解释更加清晰,并且不易出现运行时错误。