2

我试图做一个“奇怪的”(但在我的情况下很有用)函数,它可以返回一个动态列表,其 len 取决于接收者的数量。

例如:

f() 返回 None 的动态列表,因此我可以执行以下操作:

a = f()  => a = None
a, b = f()  => a=b= None
(a, b) = f() => a=b= None
(a, b, c, d, e, f) = f()  => a=b=c=d=e=f= None

我认为这可以通过生成器理解或迭代器来完成,但我被阻止了如何获得接收器的数量。也许我走错了方向。你能给我一些建议吗?

任何帮助将不胜感激。

多谢,

铁镇

4

6 回答 6

3

这在 Python 中是不可能的。右侧站点上的函数不知道调用它的上下文。右侧站点在任何名称绑定发生之前进行评估。

于 2011-11-29T15:56:07.320 回答
1

不幸的是,Python 使用 Pythonic “请求宽恕比请求许可更容易”的方法解包返回的元组。也就是说,如果你有一个声明:

a,b,c = f()

在幕后,它正在做一些事情:

try:
    a = returned[0]
    b = returned[1]
    c = returned[2]
except IndexError:
    raise ValueError('need more than k values to unpack')

try:
    _ = returned[4]
except IndexError:
    pass
else:
    raise ValueError('too many values to unpack')

所以它动态地发现返回的值的数量。不幸的是,这使我们无法聪明并创建一种新的类型来处理变量返回:

class VariableReturn(object):
    def __getitem__(self, index):
        return ...

在 Python 3 中,您可以按照您的要求做一些事情,但负担在调用者身上,而不是被调用的函数。该函数应始终返回相同数量的结果,但我们将使用扩展元组解包捕获剩余的结果,如StackOverflow 问题所示。

使用这种方法,您可以返回任意数量的结果,但在最大情况下,您需要始终返回至少尽可能多的结果。其余的被打包成一个尾随元组。

a,*others = f()
a,b,*others = f()
a,b,c,*others = f()
于 2011-11-29T17:17:18.553 回答
1

如果您不介意使用 Python 3,则可以忽略不需要的内容,例如:

a, b, c, d, *_ = (x for x in range(100))
于 2011-11-29T16:12:18.887 回答
0

尝试这个:

def f(n):
    return (None, ) * n

例如:

a, b, c = f(3)

...这就是你所能得到的,因为在 Python 中,无法知道赋值左侧有多少变量。

于 2011-11-29T16:00:36.787 回答
0

做不到。

Python 中的函数只返回一个值。虽然它有时可能看起来更多,但它仍然只是一个值:一个元组。多重赋值就是一个元组解包的过程。

然后可以重申您的问题:我们是否可以根据需要解压缩的值来创建一个充当不同长度的元组的对象?而这根本不是一种选择。

可能我能想到的最接近的是使用生成器并获得所需数量的项目itertools.islice

a = itertools.count()
x, y, z = itertools.islice(a, 3) # 0, 1, 2
u, v = itertools.islice(a, 2)    # 3, 4

但这与所希望的相差甚远。

于 2011-11-29T16:15:49.353 回答
0

不太好,但也许这可以帮助你:

def f(x):
    for i in x:
        globals()[i] = None

f(['a','b','c'])
于 2011-11-29T16:23:00.583 回答