List Comprehensions: Printing

When using list comprehensions (instead of for loops), why does the resulting list print out as a “generator object” with a memory reference? I tried converting the generated object into a list with list(<object>), but it isn’t working as expected. What am I doing wrong?

x for x in iterable

That is a generator but we can unpack it by giving it an object wrapper…

[x for x in iterable]

That object is a list, nonconsumable, which means we can reuse it once assigned. The generator consumed itself making the list.

If you’re like me, it will be easier to get a feel for the mechanics than fully comprehend the underlying dunder methods. Sooner or later you will want to get more intimate with Python, which is completely transparent and has no secrets, just lots of rabbit holes. Get a grip on that level and Python is your oyster. Still, at my level it is a promise kept.

>>> x = "astring"
>>> y = [c for c in x]
>>> y
['a', 's', 't', 'r', 'i', 'n', 'g']
>>> 

This gets the same result on a string iterable as invoking the list constructor…

>>> z = list(x)
>>> z
['a', 's', 't', 'r', 'i', 'n', 'g']
>>> 

Since a str can be unpacked,

>>> u = [*x]
>>> u
['a', 's', 't', 'r', 'i', 'n', 'g']
>>> 

Pardon that we neglected to ask to see your code and output. May we see that, for a better idea of what your question is about?

Unpacking strings is kind of boring unless we actually need those letters and their index. What’s the point of creating an iterable from an iterable?

Lots of situations arise where this basic understanding is useful. Say we want to add all the digits of a number without using any arithmetic but addition.

>>> x = 1234
>>> y = sum([int(u) for u in str(x)])
>>> y
10
>>> 

Oh, yeah, did we mention that printing is not possible in a comprehension? That would involve a statement.

An expression cannot contain any statements, only other expressions. It’s for the same reason we cannot use .append(), &c. in a comprehension. It is an expression, and must always be treated as one. Generators figure into this sort of declarative programming.

Expressions can be returned as tangible values. Statements, as return values will always be, None. It warns us that procedures do not belong in return statements unless we can disregard their return value.

1 Like

Hi, mtf.

Hmmm. Maybe it was just a hiccup with the lesson I was on at the time. I tried printing a list that was made via comprehension, and that’s when it printed out the “generator object” instead of the expected list. However, now when I try it again (with the code below), it works fine …

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

list_b = [(n + 1) for n in list_a if (n % 2 == 0)] 

print(list_b) 
1 Like