python - 有没有办法在解包时将 splat-assign 分配为元组而不是列表?

标签 python python-3.x list tuples iterable-unpacking

我最近惊讶地发现“splat”(一元 *)运算符总是将切片捕获为 list在项目解包期间,即使被解包的序列具有另一种类型:

>>> x, *y, z = tuple(range(5))
>>> y
[1, 2, 3]  # list, was expecting tuple
与不拆包的情况下如何编写此作业进行比较:
>>> my_tuple = tuple(range(5))
>>> x = my_tuple[0]
>>> y = my_tuple[1:-1]
>>> z = my_tuple[-1]
>>> y
(1, 2, 3)
它也与 splat 运算符在函数参数中的行为方式不一致:
>>> def f(*args):
...     return args, type(args)
...
>>> f()
((), <class 'tuple'>)
为了追回y作为解包后的元组,我现在必须写:
>>> x, *y, z = tuple(range(5))
>>> y = tuple(y)
这仍然比基于切片的语法好得多,但仍然受到我认为非常不必要和意外的优雅损失的影响。有什么办法可以恢复y作为元组而不是没有后分配处理的列表?
我试图强制 python 解释 y写成元组 x, *(*y,), z = ... ,但它最终仍然是一个列表。当然还有诸如 x, *tuple(y), z 之类的蠢事don't work in python .
我目前正在使用 Python 3.8.3,但也欢迎涉及更高版本(可用时)的解决方案/建议/解释。

最佳答案

这是设计使然。引用有关分配的官方文档:

...The first items of the iterable are assigned, from left to right, to the targets before the starred target. The final items of the iterable are assigned to the targets after the starred target. A list of the remaining items in the iterable is then assigned to the starred target (the list can be empty).


Python 用户极有可能想要改变您的 y之后,所以list类型是在 tuple 上选择的.
引用 PEP 3132 的接受部分我通过 this 中的链接找到的相关问题:

After a short discussion on the python-3000 list [1], the PEP was accepted by Guido in its current form. Possible changes discussed were:

  • Only allow a starred expression as the last item in the exprlist. This would simplify the unpacking code a bit and allow for the starred expression to be assigned an iterator. This behavior was rejected because it would be too surprising.

  • Try to give the starred target the same type as the source iterable, for example, b in a, *b = "hello" would be assigned the string "ello". This may seem nice, but is impossible to get right consistently with all iterables.

  • Make the starred target a tuple instead of a list. This would be consistent with a function's *args, but make further processing of the result harder.


所以用 y = tuple(y) 转换之后是你唯一的选择。

关于python - 有没有办法在解包时将 splat-assign 分配为元组而不是列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61399162/

相关文章:

python - pandas DataFrame 中最大值对应的列名

python - 创建可变数量的类实例

c# - 检查字符串是否包含 Enumerable.Range 过滤器列表中的匹配项

android - 写一个List到内部存储onPause(),然后读取List onResume()

python - 没有名为 openai 的模块

python - 如何解决使用 Python 读取和写入 HDFS 时的代理错误?

python - 在 python 脚本中使用 IPMI (OpenIPMI)

python - 如何通过 SWIG 在 Python 和 C 之间编码指向 cstring 的指针

python - 在python中加入xml element.text

Python,在字典中查找与规则匹配的组件