Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What does <generator object <generator object <genexpr> at 0x0402C7B0> mean?

309 views
Skip to first unread message

CrazyVideoGamez

unread,
May 21, 2019, 9:11:21 PM5/21/19
to
I tried doing a list comprehension. I typed:

favorite_fruits = ['watermelon', 'blackberries']
print(fruit for fruit in favorite_fruits)

And I got:

<generator object <genexpr> at 0x0402C7B0>

What does this mean and what do I have to fix?

Chris Angelico

unread,
May 21, 2019, 9:26:51 PM5/21/19
to
It means that you just printed out a generator object. But to "fix"
this, you first have to explain what you wanted.

ChrisA

Terry Reedy

unread,
May 21, 2019, 9:42:25 PM5/21/19
to
On 5/21/2019 9:11 PM, CrazyVideoGamez wrote:
> I tried doing a list comprehension. I typed:
>
> favorite_fruits = ['watermelon', 'blackberries']
> print(fruit for fruit in favorite_fruits)
>
> And I got:
> <generator object <genexpr> at 0x0402C7B0>
> What does this mean

It means that the expression (fruit for fruit in favorite_fruits)
evaluates to a generator object.

> and what do I have to fix?

Perhaps you wanted to run the generator, perhaps like this:

>>> favorite_fruits = ['watermelon', 'blackberries']
>>> print(*(fruit for fruit in favorite_fruits))
watermelon blackberries

--
Terry Jan Reedy

Cameron Simpson

unread,
May 21, 2019, 9:51:18 PM5/21/19
to
It means you didn't make a list comprehension. You've discovered a
similar thing though.

A list comprehension includes square brackets:

[ fruit for fruit in favorite_fruits ]

The result of that expression is literally a list, in this case
effectively a copy of your favorite_fruits list.

However, what you wrote was this:

fruit for fruit in favorite_fruits

and that is a generator expression. It is effectively an object that you
can iterate over, and it will yield the elements from favourite_fruits.

Importantly, it doesn't construct a list. It constructs a tiny function.

Why might we want such a thing? Because it is "lazy": it only computes
values which are actually asked for (consumed). The list comprehension
computes all the values, _and_ allocates a list and stores them! This
consumes more memory (except for small lists) and stalls your programme
while that work takes place.

It is equivalent to this function:

def elements_of(some_list):
for element in some_list:
yield element

That is a "generator function", and when you call it eg
"elements_of(favorite_fruits)" it doesn't run. Instead it returns you a
generator object which is effectively a call to the function frozen in
time.

The generator object is iterable, and when you iterate over it if fires
up the frozen function. The function runs until it hits a yield
statement, where it yields a value and that is the next value for the
iteration; the function freezes again then.

Consider this loop:

stop_at = 'watermelon'
for value in [ fruit for fruit in favorite_fruits ]:
print(value)
if value == stop_at:
break

This (a) constructs a list containing all the elements of
favorite_fruits then (b) iterates over the elements of that list. When
it hits a particular one of those elements it exits the loop.

If we unfold the "for" line a little:

elements = [ fruit for fruit in favorite_fruits ]
for value in elements:

The same amount of work is done, it just makes clear that the list
construction is a whole distinct step.

Now compare (generator expression in brackets, for clarity.:

stop_at = 'watermelon'
elements = fruit for fruit in favorite_fruits
for value in elements:
print(value)
if value == stop_at:
break

Now "elements" is not a list, it is a generator expression. You can
still iterate over this, and the printed output will be the same.
However, before the "for", _no_ elements of favorite_fruits have been
iterated over - almost no work has happened at all. Then as the for loop
iterates, it fetches values from "elements", which yields them as
needed.

So that when the loop stops early, no effort (or memory storage) is
wasted looking at the tail of the list.

Your list is very small, but for large lists this is a significant win.
Some lists are (notionally) infinitely large.

Cheers,
Cameron Simpson <c...@cskk.id.au>

Paul Moore

unread,
May 22, 2019, 6:26:27 AM5/22/19
to
On Wed, 22 May 2019 at 02:45, Terry Reedy <tjr...@udel.edu> wrote:
>
> On 5/21/2019 9:11 PM, CrazyVideoGamez wrote:
> > I tried doing a list comprehension. I typed:
> >
> > favorite_fruits = ['watermelon', 'blackberries']
> > print(fruit for fruit in favorite_fruits)
> >
> > And I got:
> > <generator object <genexpr> at 0x0402C7B0>
> > What does this mean
>
> It means that the expression (fruit for fruit in favorite_fruits)
> evaluates to a generator object.
>
> > and what do I have to fix?
>
> Perhaps you wanted to run the generator, perhaps like this:
>
> >>> favorite_fruits = ['watermelon', 'blackberries']
> >>> print(*(fruit for fruit in favorite_fruits))
> watermelon blackberries

Or maybe you just wanted a loop?

for fruit in favorite_fruits:
print(fruit)

Generator and list comprehension syntax is a somewhat more advanced
feature of Python (not *very* advanced, particularly in the case of
list comprehensions, but enough so to be tricky for a newcomer). I
don't know how much experience the OP has with Python, but as a
general rule, it's always better to stick with the simplest approach
that does what you want, and statements like loops are simpler than
complex one-line expressions (even if the complex one liners make you
look cool ;-))

Paul

inhahe

unread,
May 22, 2019, 7:17:21 AM5/22/19
to
Short answer: (some generator expression) is for iterating over, as others
have said. try this:
print([fruit for fruit in favorite_fruits])

a loop would work too, as someone mentioned, but the result would be
different. you'd get your fruits separated by line breaks (or something
else if you specify that), and with no quotation marks, instead of in list
form.

also note: print(favorite_fruits) will do the same thing as print([fruit
for fruit in favorite_fruits]) so there's no need to put a list
comprehension there.

On Tue, May 21, 2019 at 9:16 PM CrazyVideoGamez <jasona...@gmail.com>
wrote:
> --
> https://mail.python.org/mailman/listinfo/python-list
>
0 new messages