生成器表达式中的多个产量?蟒

时间:2017-11-19 17:31:03

标签: python generator yield generator-expression

我一直在尝试将此生成器函数转换为生成器表达式,但没有成功。是否可以使用生成器表达式生成相同的输出?

    def gen5(num):
         for i in range(num):             
             yield i *2
             yield i *10
             yield i *i

    g = gen5(4) 
    list(g)
    [0, 0, 0, 2, 10, 1, 4, 20, 4, 6, 30, 9]

我已尝试过以下操作,但请输入(无,无,无)输出。

    gen_exp2 = (((yield u*2), (yield u*10) ,(yield u*u)) for u in  range(4))

    list(gen_exp2)

    [0,
     0,
     0,
     (None, None, None),
     2,
     10,
     1,
    (None, None, None),
     4,
    20,
     4,
    (None, None, None),
    6,
    30,
    9,
   (None, None, None)]

我也做过这个,但它提供了4个嵌套元组而不是上面的列表。

       gen_exp3 = (((i*2), (i*10), (i*i)) for i in range(4))

       list(gen_exp3)

       [(0, 0, 0), (2, 10, 1), (4, 20, 4), (6, 30, 9)]

另外,如何在生成器表达式中添加参数? 非常感谢提前。

2 个答案:

答案 0 :(得分:3)

你只需要在gen exp中使用双循环:

num = 4
g = (j for i in range(num) for j in (i*2, i*10, i*i))
print(*g)

<强>输出

0 0 0 2 10 1 4 20 4 6 30 9

正如摩西所说,在gen exp中使用yield并不是一个好主意。

这是一个可爱的变体,使用map

g = (j for i in range(num) for j in map(i.__mul__, (2, 10, i)))

但是,有些人可能不喜欢使用i.__mul__

您问:“如何在生成器表达式中添加参数?”。好吧,你做不到。你可以 创建一个lambda,正如摩西所展示的那样,但实际上你最好做一个合适的生成器功能。 Lambdas应该是匿名函数,因此创建一个lambda并将其绑定到一个名称是一个相当可疑的实践。 ;)

答案 1 :(得分:2)

您不需要在生成器表达式中使用yield

请参阅yield in list comprehensions and generator expressions,了解为什么这很容易被视为错误,尽管不是。

您可以使用嵌套理解在生成器表达式中实现相同的功能:

gen_exp2 = (x for u in range(4) for x in (u*2, u*10, u*u))

您可以通过将生成器表达式放在函数中来对此进行参数化:

gen_fun = lambda num: (x for u in range(num) for x in (u*2, u*10, u*u)) 

可能更好地保留原始方法,因为在函数中使用yield可能比在生成器表达式中使用嵌套理解更快,而在没有嵌套的情况下已经非常慢。