Reputation: 896
I've been trying to convert this generator function into a generator expression, but with no success. Is it possible to have the same output with a 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]
I've tried the following, but get this (None, None, None) output.
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)]
I've also done this, but it gives 4 nested tuples instead of the list above.
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)]
Also, how can I add a parameter to a generator expression? Many thanks in advance.
Upvotes: 4
Views: 4592
Reputation: 55469
You just need a double loop in the gen exp:
num = 4
g = (j for i in range(num) for j in (i*2, i*10, i*i))
print(*g)
output
0 0 0 2 10 1 4 20 4 6 30 9
As Moses says, using yield
in a gen exp is not a good idea.
Here's a cute variation, using map
g = (j for i in range(num) for j in map(i.__mul__, (2, 10, i)))
However, some people might not like that use of i.__mul__
.
You asked: "How can I add a parameter to a generator expression?". Well, you can't. You could create a lambda
, as Moses shows, but really you're better off making a proper generator function. Lambdas are supposed to be anonymous functions, so creating a lambda and binding it to a name is a rather dubious practice. ;)
Upvotes: 3
Reputation: 78556
You don't need to use yield
in a generator expression.
See yield in list comprehensions and generator expressions on why this could easily be considered a bug, although it isn't.
You can use a nested comprehension to achieve the same thing in a generator expression:
gen_exp2 = (x for u in range(4) for x in (u*2, u*10, u*u))
And you can parameterise this by putting the generator expression in a function:
gen_fun = lambda num: (x for u in range(num) for x in (u*2, u*10, u*u))
Might be better to keep your original approach though, as using yield
in a function may be faster than using a nested comprehension within a generator expression which is already pretty slow without nesting.
Upvotes: 2