我最近惊讶地发现“splat”(一元 *)运算符总是list在项目解包期间将切片捕获为 a ,即使被解包的序列具有另一种类型:
>>> x, *y, z = tuple(range(5))
>>> y
[1, 2, 3] # list, was expecting tuple
Run Code Online (Sandbox Code Playgroud)
与不拆包的情况下如何编写此作业进行比较:
>>> my_tuple = tuple(range(5))
>>> x = my_tuple[0]
>>> y = my_tuple[1:-1]
>>> z = my_tuple[-1]
>>> y
(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)
它也与 splat 运算符在函数参数中的行为方式不一致:
>>> def f(*args):
... return args, type(args)
...
>>> f()
((), <class 'tuple'>)
Run Code Online (Sandbox Code Playgroud)
为了y在解包后恢复为元组,我现在必须写:
>>> x, *y, z = tuple(range(5))
>>> y = tuple(y)
Run Code Online (Sandbox Code Playgroud)
这仍然比基于切片的语法好得多,但仍然受到我认为非常不必要和意外的优雅损失的影响。有没有办法在y没有分配后处理的情况下恢复为元组而不是列表?
我试图y通过写入来强制 python …
这个问题源于PEP 448- 其他解包通用化,并且据我所知(并且没有后端移植到2.x),它存在于Python 3.5中.具体而言,在" 缺点 "一节中,注意到以下内容:
虽然
*elements, = iterable原因elements是一list,elements = *iterable,导致elements成为一个tuple.造成这种情况的原因可能会让那些不熟悉这种结构的人感到困惑.
确实如此,因为iterable = [1, 2, 3, 4]第一种情况产生了list:
>>> *elements, = iterable
>>> elements
[1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)
而对于第二种情况tuple,创建了一个:
>>> elements = *iterable,
>>> elements
(1, 2, 3, 4)
Run Code Online (Sandbox Code Playgroud)
由于不熟悉这个概念,我很困惑.谁能解释这种行为?已加星标的表达方式是否会根据其所在的方式而有所不同?
在Python中,我可以写这样的东西:
some_list = [(1, 2, 3), (3, 2, 1)]
for i, *args in some_list:
print(args)
Run Code Online (Sandbox Code Playgroud)
我将得到下一个输出:
[2, 3]
[2, 1]
Run Code Online (Sandbox Code Playgroud)
当我们用作*args函数参数时,它会被解压缩到tuple.
为什么我们会list在这种情况下收到 a ?