Python解包操作符(*)

26

我正在研究Python代码高尔夫,看到有人以奇怪的方式使用了解包运算符:

*s,='abcde'

我知道解包运算符基本上是对序列进行迭代。所以我知道

s=[*'abcde']
s变量中存储['a','b','c','d','e']的代码将“解包”abcde字符串。

有人能尽可能详细地解释一下这个代码是如何工作的吗?

*s,='abcde'

这个语句的作用是什么?我知道它与s=[*'abcde']有相同的效果,但它是以一种不同的方式实现的。为什么要对变量进行解包迭代,而不是对字符串进行解包迭代?为什么变量名后面会有逗号?


4
我对这是否是在赋值语句中左右两侧使用星号运算符的重复问题存在矛盾。无论如何,答案应该有助于那里的解决。 - miradulo
1
@miradulo,我已经阅读了这个问题及其答案,有些事情已经澄清了。尽管如此,我仍然对变量名后面的逗号的使用感到困惑。这是否与s将成为列表有关? - Fabián Montero
2
为了在 lhs 上使用 *,lhs 需要是逗号分隔列表或 [ ]。尾随逗号创建一个仅包含一个项目的逗号分隔列表,相当于 [*s]='abcde',但多了一个字符。 - AChampion
2个回答

34

这是可迭代对象拆包。您可能已经在其他地方看到过它,用于从单个表达式中为多个变量分配值。

a, b, c = [1, 2, 3]

这个语法包括一个*,表示这个变量应该是一个列表,其中包含未明确分配给其他变量的可迭代元素。

a, *b, c = [1, 2, 3, 4, 5]
print(b)
# [2, 3, 4]

那么,在你的例子中发生了什么?只有一个变量名被分配,因此它将获取未分配给另一个变量的所有项,在这种情况下是所有项。如果您尝试

*s='abcde'

你会得到

SyntaxError: starred assignment target must be in a list or tuple

这就是为什么会有那个逗号的原因,因为一个尾随逗号是用来指示一个单值元组的。


4
“PEP 3132” 的含义是:“在简单赋值语句的左侧,出现了一个元组(或列表)…” - Patrick Haugh

3
只有在创建单个元组时(也称为单例),才需要使用尾逗号;在所有其他情况下,尾逗号都是可选的。没有尾逗号的单个表达式不会创建元组,而是产生该表达式的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接