flame boi
flame boi

Reputation: 41

How do I create a generator within a generator- Python

If I created a list:

_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

and tried to get every value <= 6 by using a generator:

test = next(i for i in a for a in _list if i <= 6)

(btw this doesn't work ↑↑↑↑↑)

How do I iterate through lists within a list using a generator? If this is not possible, what method can I use in place of this?

I have looked here: python generator of generators?, but could not find an answer...

Upvotes: 0

Views: 1718

Answers (5)

Sunitha
Sunitha

Reputation: 12015

>>> t = (i for a in _list for i in a if i <= 6)
>>> next(t)
1
>>> next(t)
2
>>> next(t)
3
>>> next(t)
4
>>> next(t)
5
>>> 

Use list to convert the iterator to a list

>>> t = (i for a in _list for i in a if i <= 6)
>>> list(t)
[1, 2, 3, 4, 5, 6]

Upvotes: -1

Sunitha
Sunitha

Reputation: 12015

You can combine itertools.takewhile and itertools.chain to create an iterator matching your requirements

>>> from itertools import chain, takewhile
>>> itr = takewhile(lambda i: i<=6, chain(*_list))
>>> print (list(itr))
[1, 2, 3, 4, 5, 6]

Upvotes: 0

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140178

in that case, you don't need to create a generator of generator. Just create a double for loop in one generator (to flatten the list, then test for the element values):

_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

gen = (x for sublist in _list for x in sublist if x <= 6)

this double for comprehension syntax needs some using to, comprehensions are generally written "the other way round", but not in the case of loops, hence your confusion. A more general form would be:

(expression(item) for sublist in input_list for item in sublist if condition(item))

then to get the first matching element:

print(next(gen,None))  # None is printed if there's no matching element

(to get all the elements, of course you have to iterate on gen, next provides the "next" values, like if you're iterating "manually" on your generator)

Upvotes: 2

Andrej Kesely
Andrej Kesely

Reputation: 195438

Using chain from builtin module itertools:

from itertools import chain

_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

print(list(i for i in chain.from_iterable(_list) if i <= 6))

Output:

[1, 2, 3, 4, 5, 6]

What itertools.chain does? According manual pages:

Make an iterator that returns elements from the first iterable until it is exhausted, then proceeds to the next iterable, until all of the iterables are exhausted. Used for treating consecutive sequences as a single sequence.

Upvotes: 7

nosklo
nosklo

Reputation: 222852

to nest two fors in the same generator you must reverse the order

test = next(i for a in _list for i in a if i <= 6)

Upvotes: 1

Related Questions