Python:将参数传递给由生成器表达式创建的生成器对象?

har*_*777 7 python python-3.x

所以我有这个 gen 对象:

yld123cu = (x * u for x in range(1, 4))
Run Code Online (Sandbox Code Playgroud)

我只能这样使用:

u = 2  # some user given value
for i in yld123cu:
    print(i, end=' ')
Run Code Online (Sandbox Code Playgroud)

是否有任何语法可以避免使用 u=.. 赋值的额外行?有什么方法可以将 u 值放入 for 语句中?

我想要类似于下面的东西,但使用 gen 表达式,而不是函数:

def yld123u(u):
    for i in range(1, 4):
        yield i * u

for i in yld123u(2):
    print(i, end=' ')
Run Code Online (Sandbox Code Playgroud)

Oli*_*çon 9

由于生成器表达式不能有自己的范围,因此首选方法是按照您的建议定义生成器函数。

def yld123u(u):
    for i in range(1, 4):
        yield i * u
Run Code Online (Sandbox Code Playgroud)

如果您需要u一路更新并且这就是您想要避免上述情况的原因,那么请知道您可以send为生成器设置一个值。

def yld123u(u):
    for i in range(1, 4):
        received = yield i * u # a sent value will be assigned to 'received'
        u = u if received is None else received
Run Code Online (Sandbox Code Playgroud)

例子

如果您不使用发送,生成器的行为仍然相同。

for x in yld123u(4):
    print(x)
Run Code Online (Sandbox Code Playgroud)

输出

4
8
12 
Run Code Online (Sandbox Code Playgroud)

您可以使用send来更新 的值u

gen = yld123u(4)
v0 = next(gen)
v1 = gen.send(0)
v2 = gen.send(4)
print(v0, v1, v2)
Run Code Online (Sandbox Code Playgroud)

输出

4 0 12
Run Code Online (Sandbox Code Playgroud)

输入回路

如果您需要生成器与用户输入进行交互,这里是我过去的回答,它提出了一种实现可在 for-loop 中使用yield-receive 生成​​器的方法

class YieldReceive:
    stop_iteration = object()

    def __init__(self, gen):
        self.gen = gen
        self.next = next(gen, self.stop_iteration)

    def __iter__(self):
        return self

    def __next__(self):
        if self.next is self.stop_iteration:
            raise StopIteration
        else:
            return self.next

    def send(self, value):
        try:
            self.next = self.gen.send(value)
        except StopIteration:
            self.next = self.stop_iteration
Run Code Online (Sandbox Code Playgroud)

用法

it = YieldReceive(yld123u(4))
for x in it:
    print(x)
    it.send(int(input('Enter next u value: ')))
Run Code Online (Sandbox Code Playgroud)

  • 嘿奥利维尔,非常感谢您提供出色的洞察力和细节!以及发送方法的链接。一整天都在玩 pycharm 调试器,让我头晕目眩..所以 gen 函数 + send/next 是要走的路,好吧。我在 c-family 之后才学习 Python 几个星期,昨天刚到 oop 部分,所以也很喜欢单步学习你的课堂样本。如此崇高的工作,你如此慷慨地帮助人们,祝你一切顺利!! (3认同)