5

免责声明:我正在寻找 Python 2.6 解决方案,如果有的话。

我正在寻找一个函数,它在传递单个值时返回单个值,或者在传递多个值时返回一个序列:

>>> a = foo(1)
2
>>> b, c = foo(2, 5)
>>> b
3
>>> c
6

需要明确的是,这是为了使某些函数调用看起来比:

a, = foo(1)

或者

a = foo(1)[0]

现在,不优雅的解决方案是这样的:

def foo(*args):
    results = [a + 1 for a in args]
    return results if len(results) > 1 else results[0]

是否有任何语法糖(或功能)可以让这种感觉更清晰?类似以下内容?

def foo(*args):
    return *[a + 1 for a in args]
4

5 回答 5

7

如果这对您更好,您总是可以编写一个装饰器来省略该 if 语句:

import functools
def unpacked(method):
    @functools.wraps(method)
    def _decorator(*args):
        result = method(*args)
        return results if len(results) != 1 else results[0]
    return _decorator

用法:

@unpacked
def foo(*args):
    return [arg + 1 for arg in args]
于 2010-10-27T00:06:08.443 回答
6

如果列表只有一个元素,您可以轻松编写一个scalify从列表中返回元素的函数,即它试图使其成为标量(因此得名)。

def scalify(l):
    return l if len(l) > 1 else l[0]

然后你可以在你的函数中使用它,如下所示:

def foo(*args):
    return scalify([a + 1 for a in args])

这可以解决问题,但我支持那些建议你不要这样做的人。出于一个原因,它排除了对结果的迭代,除非您知道您至少传递了两个项目。此外,如果您有一个列表,则在调用该函数时必须解包该列表,从而失去其“列表性”,并且您知道您可能无法取回列表。在我看来,这些缺点掩盖了您对该技术可能看到的任何好处。

于 2010-10-27T00:39:44.710 回答
0

你的意思是你想要一个具有相同数量参数的元组?这不是解决方案吗?

return tuple([a + 1 for a in args])

于 2010-10-27T00:06:35.413 回答
0
def foo(*args):
    return (None, args[0]+1 if args else None, map(lambda a: a + 1, args))[len(args) if len(args) < 3 else 2]

:-) 这是地狱

于 2010-10-27T00:07:45.960 回答
0

这将处理 0 个或更多参数,我认为这就是您要寻找的。

def foo(*args):
    return map(lambda x: x + 1, args) or [None]

编辑:我修改为添加一个 None 列表以防打开 0 args

于 2010-10-27T00:08:43.900 回答