天道酬勤,学无止境

优雅的拆包变长元组(elegant unpacking variable-length tuples)

问题

一个真实的,如果愚蠢的问题:

https://github.com/joshmarshall/tornadorpc/blob/master/tornadorpc/base.py

def start_server(handlers, ...):
    ...
    for (route, handler) in handlers:
        ...

通常“处理程序”是 2 元素元组的列表。 但是使用这个特定的解决方案(Tornado),您可以将第三个参数传递给特定的处理程序(kw args)。 因此,“处理程序”中的元组有时可能有 2 个元素,有时也可能有 3 个元素。

我需要循环解压。 当然,我可以做一些像长度检查或尝试..除了拆包。 啊。

你能想出比这更好/更聪明的事情吗:

In [8]: handlers
Out[8]: [(1, 2), (3, 4, 5), (6, 7)]


In [9]: new_handlers = [x + (None,) for x in handlers]

?

回答1

如果该处理程序采用关键字参数,则对第三个元素使用字典:

handlers = [(1, 2, {}), (3, 4, {'keyword': 5), (6, 7, {})]

for route, handler, kwargs in handlers:
    some_method(route, handler, **kwargs)

或者您可以使用*args语法应用参数; 在这种情况下,只需捕获循环中的所有值:

for args in handlers:
    some_method(*args)

如果您必须解压缩成至少 2 个参数,请在单独的步骤中执行此操作:

for handler in handlers:
    route, handler, args = (handler[0], handler[1], handler[2:])

其中args将是 0 个或更多元素的元组。

在 Python 3 中,您可以使用 splat ( * ) 目标处理任意宽度的解包:

for route, handlers, *args in handlers:

其中*args在解包中捕获 0 个或更多额外值。

handlers中的元素缩短到最小长度的另一条路线可以通过以下方式完成:

[(h + (None,) * 3)[:3] for h in handlers]

演示:

>>> handlers = [(1, 2), (3, 4, 5), (6, 7)]
>>> [(h + (None,) * 3)[:3] for h in handlers]
[(1, 2, None), (3, 4, 5), (6, 7, None)]
回答2

从 Python 3 开始,您可以使用 PEP 3132 扩展解包:

for route, handler, *kw in handlers:
    ...

如果这不是一个选项,请与中介解包:

for handler in handlers:
    (route, handler), kw = handler[:2], handler[2:]
标签

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • python基础语法之拆包(解包)
    理解和使用python中的拆包会让我们的代码变得流畅,不仅对自己的手关节有好处,也使看官觉得很赏心悦目,既然拆包这么香那就抓紧用起来吧。 1、直接交换变量的本质 在C,C++和Java语言中如果想交换两个变量的值就必须用到第三个临时变量,但是在python中我们竟然可以做到不用经过第三方的手直接进行交换了,即省去了第三个变量又尽显优雅,那么他是如何实现的呢。 a = 1 b = 2 a, b = b, a 我们先说python中一个重要的数据结构,那就是元组,在元组( )可以省略,那么上面的a, b = b, a等式右边的b, a就自行构成了一个元组。 所以左边就变成了对元组的拆包过程。直接交换变量的实质就是一个打包和拆包的过程。 2、常见的拆包操作 1、元组的拆包 tup = (1, 2, 3) # 方式一 a, b, c = tup # 要求元组内的个数与接收的参数个数相同 print(a, b, c) 结果如下: 1 2 3 # 方式二 print(*tup) # 使用*进行拆包,结果同上 add(*tup) 如下方式是错误的 a, b, c = *tup 这两种方式分别在什么情况下使用呢? 方式一一般在要获取元组的值时使用方式二一般在函数调用时使用,见下面的函数中的装包与拆包 下面介绍一点稍微复杂一点的拆包 tup = (1, 2, 3, 4, 5, 6)
  • 字典元组列表拆包
    函数调用 *:函数调用的时候可以用来对元组或列表拆包 **:函数调用的时候可以用来对字典拆包 ======================================================= **:对字典拆包 dic = {"a": 1, "b": 2, "c": 3, "d": 4} func(**dic) 运行结果: 1 2 3 4 --------------------------------------------------------------- *:对元组的拆包 tu = (111, 222, 334, 444) func(*tu) #func(tu[0], tu[1], tu[2], tu[3]) #非拆包运行需逐个添加索引 运行结果: 111 222 334 444 ----------------------------------------------------------------------------------------------- # *: 表示接收位置参数的不定长参数 # **:表示接收关键字参数的不定长参数 def func(*a, **b): print(a) print(b) func(11, 22, 33, aa=11, bb=22, c=33) 运行结果: (11, 22, 33) {'aa': 11, 'bb
  • python3之元组和字典的拆包
    参数的拆包和解包用到的前提是:在调用带有多值参数的函数时,其中有一个定参,其他为元组或字典,为了简化传入参数,则需要拆包。 拆包方法为: 在元组变量前加一个星号* 在字典变量前增加两个星号** def demo1(num,*args): print(num) print(args) demo1(1,(2,3,4)) #输出 : 1 ((2, 3, 4),) demo1(1,2,3,4) #输出:1 (2, 3, 4) def demo(*args,**kwargs): print(args) print(kwargs) num_tuple = (1,2,3,4,5,6) student_info = {"name":"小明","age":12} print('---- 未拆包,即调用前不加星号,输出-----') demo(num_tuple,student_info) print('---- 拆包,即调用前加星号,输出:-----') demo(*num_tuple,**student_info) demo(1,2,3,4,5,6,name="小明",age=12) 输出: ---- 未拆包,即调用前不加星号,输出----- ((1, 2, 3, 4, 5, 6), {‘name’: ‘小明’, ‘age’: 12}) {} ---- 拆包,即调用前加星号,输出----- (1
  • 长元组拆解的习语[关闭](Idiom for long tuple unpacking [closed])
    问题 关门了。 这个问题是基于意见的。 它当前不接受答案。 想要改善这个问题吗? 更新问题,以便可以通过编辑此帖子以事实和引用的形式回答。 6年前关闭。 改善这个问题 方案:由于SQL查询,您有一个较长的元组,并且想将其拆成单独的值。 符合PEP8的最佳方法是什么? 到目前为止,我有以下三种选择: 单个分配,使用反斜杠拆分为多行person_id, first_name, last_name, email, \ birth_date, graduation_year, home_street, \ home_city, home_zip, mail_street, mail_city, \ mail_zip = row 单项作业,将左手组放在括号中,并在不加反斜杠的情况下将折线分组(person_id, first_name, last_name, email, birth_date, graduation_year, home_street, home_city, home_zip, mail_street, mail_city, mail_zip) = row 分为多个作业,每个作业都适合一行person_id, first_name, last_name, email = row[0:4] birth_date, graduation_year, home_street =
  • Python中的拆包和装包(可变参数)
    拆包:把一个元组拆开分别给几个变量赋值称为拆包。 例如: #拆包 t1 = (4,5,6,7) a,b,c,d = t1 print(a,b,c,d) 当用与元组个数不同的变量个数去取元组中的值时,会报错,如下所示: t1 = (4,5,6,7) #a,b = t1 ValueError: too many values to unpack (expected 2) #print(a,b) #a,b,c,d,e = t1 ValueError: not enough values to unpack (expected 5, got 4) 如果我们不想让其出现错误,这时就会用到可变参数: 格式为:*变量名 注:如果在定义函数时,既要定义可变参数,又要定义不可变参数,那么不可变参数一定要放在最前面 拆包和装包 赋值时: *x = 1,2,3 装包,把散列的1,2,3装到一个列表里,然后赋值给x,即x=[1,2,3] 打印时: print(*x)即print(*[1,2,3]) 拆包,打印:1 2 3 总结:x就是一个列表,具体值为[1,2,3];*x就是几个散列的值,1 2 3 ''' 下面放出例子以及运行结果: # 求加法的函数 def add1(*args): print(args) print(*args) return sum(args) print(add1(5, 8))
  • 如何使用列表理解将一个元组的元组转换为一维列表? [复制](How do I convert a tuple of tuples to a one-dimensional list using list comprehension? [duplicate])
    问题 这个问题已经在这里有了答案: 在Python中弄平浅表[重复] (23个答案) 7年前关闭。 我有一个元组元组-例如: tupleOfTuples = ((1, 2), (3, 4), (5,)) 我想按顺序将其转换成所有元素的平面一维列表: [1, 2, 3, 4, 5] 我一直在尝试通过列表理解来实现这一点。 但我似乎无法弄清楚。 我能够通过一个for-each循环来完成它: myList = [] for tuple in tupleOfTuples: myList = myList + list(tuple) 但是我觉得必须有一种方法来理解列表。 一个简单的[list(tuple) for tuple in tupleOfTuples]只是给您一个列表列表,而不是单个元素。 我以为可以在此基础上通过使用拆包运算符然后将列表拆包来进行构建,如下所示: [*list(tuple) for tuple in tupleOfTuples] 或者 [*(list(tuple)) for tuple in tupleOfTuples] ...但是那没用。 有任何想法吗? 还是我应该坚持下去? 回答1 它通常被称为展平嵌套结构。 >>> tupleOfTuples = ((1, 2), (3, 4), (5,)) >>> [element for tupl in
  • Python元组拆包捡到8倍镜快准狠
    元组拆包元组是不可变列表,列表是通过索引取值的,元组也是:tuple_test = (1, 2, 3) a = tuple_test[0] b = tuple_test[1] c = tuple_test[2]但Python是出了名的一行代码解决问题,元组拆包就是精髓技术之一:a, b, c = tuple_testprint("%s %s %s" % tuple_test)把元组一一对应拆出来,就叫做元组拆包。拆包有个要求,元组中的元素数量必须跟接受这些元素的空挡数一致,否则会报错:tuple_test = (1, 2, 3) a, b = tuple_test # ValueError: too many values to unpack (expected 2)_占位符使用_占位符可以解决这个问题:tuple_test = (1, 2, 3) a, b, _ = tuple_test这样就只获取到部分数据了,这在取函数返回值时特别有用,比如:import os _, filename = os.path.split("/home/dongfanger/.ssh/idrsa.pub") print(filename) # "idrsa.pub"*前缀当返回值特别多时,_占位符写起来麻烦,可以用*来处理剩下的元素:>>> a, b, *rest = range(5) >>> a
  • 元组(tuple)的常用操作
    文章目录 元组(tuple)的常用操作元组的定义元组的创建元组的删除(del)查找元组(count,index)查找(count)查找(index)通过索引取值 修改元组元素元组的拆包元组推导式列表和元祖的区别 元组(tuple)的常用操作 元组的定义 元组的定义由()定义,相邻元素之间采用,进行分割,在形式上,可以称为不可变的列表 元组是不可变类型,无法对其中的元素进行单独的修改和增加 元组的创建 # 空元祖的创建 tu = () # 一个元素的元组的创建的时候,需要在元素末尾加个, tu1 = ('hello world !',) # 多种数据类型元组的创建 tu2 = ('123', '元组', [1, 2, 3], {'name': 'zhou', 'age': 18}) # 不加小括号创建元组 tu3 = 'hello', 'world', '!' 元组的删除(del) # 删除元组tu1 tu1 = ('123', '元组', [1, 2, 3], {'name': 'zhou', 'age': 18}) del tu1 查找元组(count,index) 查找(count) tu = (11, 22, 33, 44, 55, 44, 33, 22, 11) # count查找的为某个元素在元组中出现的次数 print(tu.count(22)) # 输出结果 2 查找
  • 第7节-元组&字典&集合
    第7节-元组&字典&集合 1.元组2.拆包2.1元组的拆包:2.2列表的拆包:2.3字符串拆包: 3.字典3.1字典的定义3.2字典的创建3.3字典的使用3.4浅拷贝&深拷贝3.5 字典的遍历: 4. 集合4.1集合与列表的不同点:4.2集合的创建4.3集合的访问4.4集合的使用4.5集合的运算4.6可变对象 1.元组 (1)元组不能为空,而且至少还要有1个逗号;当元组不是空元组时,括号可以省略, 但是my_tuple=, my_tuple=(,)都会报错 (2)元组的访问/提取类似列表,通用操作与列表相同 2.拆包 2.1元组的拆包: a,b,c = (1,2,3),变量个数需与元素个数一一对应,否则会报错;如果不一致,可以在变量前面加*进行补足; a,b,*c,d = (1,2,3,4,5,6,7),*表示补足变量,补足的变量位置得到列表 注意:语句中*只能出现一次 2.2列表的拆包: my_list=[1,2,3], a,b = my_list, 注意:*补足同样适用,补足变量位置返回的也是列表 2.3字符串拆包: my_str=‘i love china’,a,b,c = my_str 注意:*补足同样适用,补足变量位置返回的也是列表 3.字典 3.1字典的定义 (1)每一个键值对我们称其为一项(item) (2)字典的键可以是任意的不可变对象(int str bool
  • Python 第七课:元组,字典及集合
    1. 元组 元组是一个不可变序列(tuple)符号为() ()是可以省略的,但当创建元组有其他元素时,必须要有==‘,’==tuple1=()空元组元组也可以存放一切 tuple1 = (1, None, False, []) 1.1 元组的拆包 这里以实例来说明: # 拆包 tuple1 = (1, 2, 3) a, b, c = tuple1 print(a, b, c) 运算得出: # 特例 tuple1 = (1, 2, 3, 4) a, b, c = tuple1 print(a, b, c) 这里会报错,因为元组tuple1中有太多值需要被拆包。 对于这个问题,引入‘*——通配符’概念 ’ * ’ 是通配符表示符号,可以代表所有,另外将转化为列表形式。 # 通配符使用举例 tuple1 = (1, 2, 3, 4) a, b, *c = tuple1 print(a, b, c) 运行得出 补充说明 字符串以及列表的拆包,类似元组拆包。 2. 字典 数据结构为映射-mapping,即查询。映射——一一对应的关系。表示形式Key-Value, 称为一个键值对,又或者称为一项。字典类型dict表示符号{}dict1 = {}是一个空字典。字典无索引 # 举例 # 正常使用 dict1 = {'name': 'David', 'Skill': 'Python', 'Age'
  • Python第七讲-元组&字典&集合
    文章目录 第七讲-元组&字典&集合7.1 元组7.2 字典的简介7.3 字典的使用7.4 字典的增删改查7.5 浅拷贝和深拷贝7.6 字典的遍历7.7 集合的简介7.8 集合的使用7.9 可变和不可变对象作业 第七讲-元组&字典&集合 7.1 元组 元组表现形式:tuple 元组为不可变序列(当我们希望数据不改变时,使用元组,其他情况一般使用列表) 使用()创建元素 当元组不是空元组时,括号可以省略 若创建的不是空元组,那么必须包含至少一个逗号(, ) 元组解包指将元组中的每一个元素都赋值给一个变量 # 元组 tuple() tuple1 = () # 创建一个空元组 tuple1 = (1, True, None, []) # 元组可以包含多种数据类型 拆包的时候必须一一对应才能拆包,否则会报错 # 元组的拆包 tuple1 = (1, 2, 3) a, b, c = tuple1 print(a) print(b) print(c) tuple2 = (1, 2, 3,4) d, e, f = tuple2 print(d) print(e) print(f) C:\Python36\python.exe C:/Python学习/第七讲.py 1 2 3 Traceback (most recent call last): File "C:/Python学习/第七讲.py"
  • 元组和字典的拆包是个蛇玩意?
    元组和字典的拆包 什么时候需要使用到拆包? 在将一个元组变量,直接传递给args 在将一个字典变量,直接传递给kwargs 就可以使用拆包,简化参数的传递 拆包的语法: 在元组变量前。增加一个 在字典变量前,增加两个 为什么管它叫做拆包: 在给函数num传参数gl_nums时智能提示会高亮显示args,表示给ags传参。 而在给它传第二个参数时还是高亮显示的是args,表示给args传参,输出结果都在一个元组中 这是为啥嘞?因为没有明确的指定给那个多值参数传参所以,两个变量的值都传给了,*args 在这里就可以使用拆包了 # 定义元组变量/字典变量 gl_nums = (1,2,3) gl_dict = {'name':'小明','age':18} num(*gl_nums,**gl_dict) # 拆包的语法 # 在元组变量前,增加一个* # 在字典变量前,增加两个* # 这样就解决了元组变量和字典变量在一个参数里的问题 如果不使用拆包语法 则把元组变量,和字典变量中的值这样写到函数的实参中 拆包语法的好处,简化参数的传递, 来源:https://blog.csdn.net/zyzgzyrmzsj/article/details/103847339
  • Django-如何在模板“ for”循环中进行元组拆包(Django - How to do tuple unpacking in a template 'for' loop)
    问题 在我的views.py中,我正在构建一个包含两个元组的列表,其中元组中的第二个项目是另一个列表,如下所示: [ Product_Type_1, [ product_1, product_2 ], Product_Type_2, [ product_3, product_4 ]] 在普通的旧Python中,我可以像这样迭代列表: for product_type, products in list: print product_type for product in products: print product 我似乎无法在Django模板中执行相同的操作: {% for product_type, products in product_list %} print product_type {% for product in products %} print product {% endfor %} {% endfor %} 我从Django收到此错误: 渲染时捕获到异常:zip参数2必须支持迭代 当然,模板中有一些HTML标记,而不是print语句。 Django模板语言不支持元组拆包吗? 还是我走错路了? 我要做的只是显示一个简单的对象层次结构-有几种产品类型,每种产品都有几种产品(在models.py中,Product具有Product_type的外键
  • 标量元组拆包(scala tuple unpacking)
    问题 我知道这个问题已经以不同的方式提出了很多次。 但是我仍然不清楚。 有没有一种方法可以实现以下目的。 def foo(a:Int, b:Int) = {} foo(a,b) //right way to invoke foo foo(getParams) // is there a way to get this working without explicitly unpacking the tuple?? def getParams = { //Some calculations (a,b) //where a & b are Int } 回答1 这是一个两步过程。 首先将foo转换为函数,然后在其上调用tupled以使其成为元组的函数。 (foo _).tupled(getParams) 回答2 @ dave-griffith死了。 您也可以致电: Function.tupled(foo _) 如果您想进入“获取比我要的信息更多的信息”领域,则还可以在部分应用的函数(和Function )中内置一些用于进行计算的方法。 一些输入/输出示例: scala> def foo(x: Int, y: Double) = x * y foo: (x: Int,y: Double)Double scala> foo _ res0: (Int, Double) => Double =
  • 元组拆包顺序更改分配的值(Tuple unpacking order changes values assigned)
    问题 我认为两者是相同的。 nums = [1, 2, 0] nums[nums[0]], nums[0] = nums[0], nums[nums[0]] print nums # [2, 1, 0] nums = [1, 2, 0] nums[0], nums[nums[0]] = nums[nums[0]], nums[0] print nums # [2, 2, 1] 但是结果是不同的。 为什么结果不同? (为什么第二个结果呢?) 回答1 先决条件-2个重点 列表是可变的列表的主要部分是列表是可变的。 这意味着可以更改列表的值。 这就是您遇到麻烦的原因之一。 请参阅文档以获取更多信息评估顺序另一部分是,在拆开元组的包装时,评估从左到右开始。 请参阅文档以获取更多信息 介绍 当您执行a,b = c,d ,首先存储c和d的值。 然后从左手侧开始,值a被第一改变为c ,然后的值b变更为d 。 这里的缺点是,如果有任何副作用的位置b同时改变的值a ,那么d被分配给后来b ,这是b受的副作用a 。 用例 现在来解决你的问题 在第一种情况下, nums = [1, 2, 0] nums[nums[0]], nums[0] = nums[0], nums[nums[0]] nums[0]最初为1而nums[nums[0]]为2因为它的计算结果为nums[1] 。 因此,现在将1
  • 《手把手陪您学Python》21——元组
    在《手把手陪您学Python》20——列表中,我们学习了列表的定义以及列表的各种操作方法。今天我们要学习的元组,可以被看做是不能修改的列表。所谓不能修改,就是不能像列表一样进行增删改的操作,而查的切片和索引方式,以及一些函数和方法与列表还是非常类似的,所以今天的内容比较容易理解,大家加油。 1、元组的定义 元组也是Python中一种常用的数据结构,它是用小括号括起来的一组数据序列。和列表一样,元组中的元素既可以是数字、布尔值、字符串、列表、变量等数据类型,也可以是包括上述元素的列表或者元组,形成多层的嵌套。同时,元组的打印结果也是用小括号括起来的元组。 In [1]: tup1 = (1, 'a', [1, 'a']) # 元组元素是数字、字符串、列表 tup1 Out[1]: (1, 'a', [1, 'a']) ​ In [2]: tup2 = (1, 'a', [1, 'a'], tup1) # 元组元素是数字、字符串、列表和变量,同时变量又是一个元组,形成嵌套 tup2 Out[2]: (1, 'a', (1, 'a'), [1, 'a']) ​ In [3]: tup3 = () # 与定义空列表的方法类似,也可以定义空元组 tup3 Out[3]: () 有了学习列表的基础,元组的定义很容易理解,但有一点是需要大家注意,首先我们看一个列子。 In [4]: tup4 =
  • elegant unpacking variable-length tuples
    A real, if silly problem: https://github.com/joshmarshall/tornadorpc/blob/master/tornadorpc/base.py def start_server(handlers, ...): ... for (route, handler) in handlers: ... Normally "handlers" is a list of 2-element tuples. But with this particular solution (Tornado) you can pass a third argument to a particular handler (kw args). So a tuple in "handlers" may have 2 elems sometimes or 3 elems other times. I need to unpack this in a loop. Sure, I can do smth like length checking or try..except on unpacking. Ugh. Can you think of smth better/more clever than this: In [8]: handlers Out[8]: [(1
  • 7、python元组&字典——旺仔
    python:元组&字典 1、数据结构简介2、元组tuple2.1、元组简介2.2、元组的表达形式及创建2.3、拆包 3、字典dict3.1、字典简介3.2、字典创建3.3、字典的修改(增删改查)3.3.1、len()3.3.2、in 与 not in3.3.3、获取值3.3.4、修改字典3.3.5、dict.setdefault添加key-value3.3.6、dict.update()3.3.7、del 关键字删除3.3.8、dict.popitem()随机删除3.3.9、dict.pop 删除3.3.10、清空字典 3.4、字典的遍历 4、深拷贝和浅拷贝4.1、什么是深拷贝和浅拷贝?4.2、实际操作 5、课后作业5.1、第一题5.2、第二题 6、附加(个人练习题——字典)统计1000个随机数中重复的数字 旺仔注: 1、数据结构简介 数据结构(Data Structures)基本上人如其名——它们只是一种结构,能够将一些数据聚合 在一起。换句话说,它们是用来存储一系列相关数据的集合。Python中有四种内置的数据结构——列表(List)、元组(Tuple)、字典(Dictionary)和集合(Set)列表在上一章博客。本章博客中将介绍元组(Tuple)、字典(Dictionary)。 2、元组tuple 2.1、元组简介   元组用于将多个对象保存到一起,近似看作列表
  • 为什么分配给一个空列表而不分配给一个空的元组是有效的?(Why is it valid to assign to an empty list but not to an empty tuple?)
    问题 这是在最近的PyCon演讲中提出的。 该声明 [] = [] 没有任何意义,但是也不会引发异常。 我觉得这一定是由于拆箱规则造成的。 您也可以使用列表对元组进行解包,例如, [a, b] = [1, 2] 符合您的期望。 作为逻辑结果,当要拆包的元素数为0时,这也应该起作用,这将解释为什么分配给空列表是有效的。 当您尝试将非空列表分配给空列表时会发生什么,进一步支持了该理论: >>> [] = [1] Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: too many values to unpack 如果元组也是如此,我将对此解释感到满意。 如果我们可以解压缩到包含0个元素的列表,那么我们也应该能够解压缩到具有0个元素的元组,不是吗? 然而: >>> () = () File "<stdin>", line 1 SyntaxError: can't assign to () 似乎拆包规则不适用于元组,就像列表一样。 对于这种不一致,我想不出任何解释。 有这种现象的原因吗? 回答1 @ user2357112的评论似乎是巧合,这似乎是正确的。 Python源代码的相关部分在Python / ast.c中: switch (e->kind) { # several
  • Python元组在return语句中解包(Python tuple unpacking in return statement)
    问题 Python 语言(尤其是 3.x)允许非常通用的可迭代解包,一个简单的例子是 a, *rest = 1, 2, 3 多年来,这种拆包已逐渐普及(参见例如 PEP 3132 和 PEP 448),使其能够在越来越多的情况下使用。 因此,我惊讶地发现以下是 Python 3.6 中的无效语法(并且在 Python 3.7 中仍然如此): def f(): rest = [2, 3] return 1, *rest # Invalid 我可以通过将返回的元组封装在括号中来使其工作,如下所示: def f(): rest = [2, 3] return (1, *rest) # Valid 我在return语句中使用它这一事实似乎很重要,因为 t = 1, *rest 确实是合法的,带括号和不带括号的结果相同。 Python 开发人员是否只是简单地忘记了这种情况,或者有什么理由说明这种情况是无效语法? 我为什么关心 这打破了我认为我与 Python 语言签订的重要合同。 考虑以下(也是有效的)解决方案: def f(): rest = [2, 3] t = 1, *rest return t 通常,当我有这样的代码时,我认为t是一个临时名称,我应该能够摆脱它,只需将底线中的t替换为其定义即可。 但是,在这种情况下,这会导致无效代码 def f(): rest = [2, 3]