10

Im studying comprehensions. I get the print(x) part (i think. It prints the value of x that passes the 'in' test) but why is it also returning a list of None afterward?

>>> g
['a', 'x', 'p']

>>> [print(x) for x in g]
a
x
p
[None, None, None] #whats this? 
Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
jason
  • 4,721
  • 8
  • 37
  • 45
  • 2
    That is the return value from `print()`. – squiguy Aug 12 '13 at 17:38
  • I dont quite understand... I thought print was returning a thenn x then p – jason Aug 12 '13 at 17:39
  • i don't think [print(x) for x in g] evaluates anything if you use python 2.7 – zs2020 Aug 12 '13 at 17:39
  • python 3 sorry forgot to say that – jason Aug 12 '13 at 17:40
  • 1
    It's worth mentioning that the correct way to do this is not to use a comprehension i.e. `for x in g: print(x)`. – Andy Hayden Aug 23 '13 at 14:57
  • @AndyHayden, curious if you could explain more. When/why should I use the loop over the list comprehension? – Tim Ernst Mar 18 '20 at 14:01
  • "I thought print was returning a then x then p" - no; it is **displaying** those letters. Returning from a function has **nothing to do with that**. A call to a function is an *expression*, and `return` tells *what the result is*. Just like how, if you compute `1 + 2 + 3`, the result from `1 + 2` does not get displayed. – Karl Knechtel Sep 14 '22 at 13:16

4 Answers4

21

print is a function (in Python3). It prints something to the screen, but returns None.

In Python2, print is a statement. [print(x) for x in g] would have raised a SyntaxError since only expressions, not statements, can be used in list comprehensions. A function call is an expression, which is why it is allowed in Python3. But as you can see, it is not very useful to use print in a list comprehension, even if it is allowed.

unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • I'd put it a little more explicitly. If you don't need a list, then don't use a list comprehension. Using a list comprehension merely for its side effects is unpythonic. – Steven Rumbalski Aug 12 '13 at 18:08
  • 1
    Right. And it is "unpythonic" because it builds a (potentially huge) list which consumes memory but is never used. – unutbu Aug 12 '13 at 18:14
  • @StevenRumbalski I've seen some pretty neat ways which leverage using *generator* expressions merely for side-effects (and I think this can be pythonic), but they wouldn't work with a print (so obviously this is not such an example). – Andy Hayden Aug 23 '13 at 14:59
9

You use a list comprehension to print the items in the list, and then the list itself is printed. Try assigning the list to a variable instead.

>>> g
['a', 'x', 'p']

>>> x = [print(x) for x in g]
a
x
p
#

Now the list is in x and isnt printed. The list is still there...

>>> print(x)
[None, None, None]
>>> x
[None, None, None]
tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • merely assigning the result to a variable causes the Nones to go away... head exploding. Tested this and youre right. – jason Aug 12 '13 at 17:45
  • 3
    The Nones are still there - they are just in variable 'x'. When you are in the interpreter, anything that is not assigned to a variable is printed. Your head can unexplode. – tdelaney Aug 12 '13 at 17:47
  • -1. I think the correct advice is to do away with the list comprehension. Assignment merely hides the error by polluting the namespace with an unnecessary name. – Steven Rumbalski Aug 12 '13 at 18:10
2
[print(x) for x in g]

is equivalent to:

l = []
for i in g:
    l.append(print(i))
return l

Print does the printing stuff, so you see the a, x and p, but it return None so the list you get in the end is [None, None, None]

Viktor Kerkez
  • 45,070
  • 12
  • 104
  • 85
1

I think you are conflating a list comprehension with str.join method.

A list comprehension always produces a new list. Three ways list may be produced that is the same as g

>>> [x for x in 'axp']
['a', 'x', 'p']
>>> [x[0] for x in ['alpha', 'xray', 'papa']]
['a', 'x', 'p']
>>> list('axp')
['a', 'x', 'p']

Since g is already strings, you use join to produce a single string to print it:

>>> g=['a', 'x', 'p']
>>> ''.join(g)
'axp'

To print it, just use join with the separator desired:

>>> print('\n'.join(g))
a
x
p

You would need to use a comprehension if the elements of the list are not compatible with join by being strings:

>>> li=[1,2,3]
>>> '\n'.join(li)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected str instance, int found
>>> print('\n'.join(str(e) for e in li))
1
2
3
dawg
  • 98,345
  • 23
  • 131
  • 206