Python 优雅的解包可变长度元组

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)]

一个真正的问题,即使是愚蠢的问题:

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

我需要把它打包成一个循环。当然,我可以做smth,比如长度检查,或者尝试……除了打开包装。啊

你能想到比这更好/更聪明的smth吗:

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:]