Python 优雅的解包可变长度元组
一个真正的问题,即使是愚蠢的问题: 通常“handlers”是一个2元素元组列表。但是使用这个特定的解决方案(Tornado),您可以将第三个参数传递给特定的处理程序(kw args)。所以“handlers”中的元组有时可能有2个元素,有时可能有3个元素 我需要把它打包成一个循环。当然,我可以做smth,比如长度检查,或者尝试……除了打开包装。啊 你能想到比这更好/更聪明的smth吗:Python 优雅的解包可变长度元组,python,tuples,Python,Tuples,一个真正的问题,即使是愚蠢的问题: 通常“handlers”是一个2元素元组列表。但是使用这个特定的解决方案(Tornado),您可以将第三个参数传递给特定的处理程序(kw args)。所以“handlers”中的元组有时可能有2个元素,有时可能有3个元素 我需要把它打包成一个循环。当然,我可以做smth,比如长度检查,或者尝试……除了打开包装。啊 你能想到比这更好/更聪明的smth吗: In [8]: handlers Out[8]: [(1, 2), (3, 4, 5), (6, 7)]
In [8]: handlers
Out[8]: [(1, 2), (3, 4, 5), (6, 7)]
In [9]: new_handlers = [x + (None,) for x in handlers]
?如果处理程序采用关键字参数,则对第三个元素使用字典:
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)
如果必须将其分解为至少两个参数,请在单独的步骤中进行:
for handler in handlers:
route, handler, args = (handler[0], handler[1], handler[2:])
其中,args
将是由0个或多个元素组成的元组
在Python 3中,您可以使用splat(*
)目标处理任意宽度的解包:
其中*args
捕获解包中的0个或更多额外值
另一条路径是将处理程序中的元素连接到最小长度,可以通过以下方法完成:
[(h + (None,) * 3)[:3] for h in handlers]
演示:
由于Python 3,您可以使用扩展解包:
for route, handler, *kw in handlers:
...
如果这不是一个选项,请使用中间层解包:
for handler in handlers:
(route, handler), kw = handler[:2], handler[2:]
我知道,但处理程序不是我的问题,我的问题是可变长度元组序列上的“for”循环。(由于tornadorpc不是我的代码/项目,我更感兴趣的是这类问题的一般解决方案,而不是特定的tornado/tornadorpc)@JohnDoe:但如果你以不同的方式对待它,问题就会消失。在任何情况下,我已经添加了通用选项。您的解包行失败,出现ValueError:解包需要2个以上的值,因为右侧有一个包含两个值的元组。很抱歉,这不太有效:ValueError:解包需要2个以上的值。我可以通过做(r,h),kw=h[:2],h[2:],但kw本身就是一个元组(比如(5,)或())。
>>> 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)]
for route, handler, *kw in handlers:
...
for handler in handlers:
(route, handler), kw = handler[:2], handler[2:]