I see such questions so often, there should be some ultimate answer to them all, which automatically triggers whenever print
and None
are both present in a single question...
While the answer to the question itself is trivial, what, I think, you need to really understand is a difference between a side effect and a return value. For example:
a = 10
def three(x):
global a
a += x #side effect
print x #side effect
return 3 #returning
The value our three()
function returns is 3. It also has two side effects: modifying a global variable a
and printing. Those are called side effects because they modify something outside of the function: the a
variable and the screen state, respectively.
In your example:
def print0(s):
print s
there's no explicit return value, only a side effect (printing). In other words, it prints something on the screen and then returns nothing. That nothing is called None
in Python. If you call it like this:
a = print0(3)
it prints 3 into the console. But what is the value of a
now?
>>> print a
None
Now to the list comprehension. It is a concept borrowed from functional programming (Lisp, etc.) where it's called map
. There's still map
function in Python, so the following two lines are equivalent:
[print0(s) for s in seqs]
map(print0, seqs)
What they both do is taking the elements of the input list (seqs
), one by one, applying the function (print0
) to each of them and putting the results (return values), one by one, into the output list, which they return. Each time they call your print0
function, it prints its argument s
on the screen (a side effect) and then returns nothing (None
), which is put into the output list by list comprehension or map
. If you do it in the Python interactive console, that result appears in the output ([None, None]
), if not - it is still produced by the interpreter and immediately discarded, unless you pass it as an argument to another statement. Which leads us to your final line of code and the TypeError
message. You pass your function to another function, which expects a string, it doesn't care about the side effects your function may produce. The context is not completely clear to me, but you probably should define your function like this:
def print0(s):
return str(s)
Now, instead of printing s
on the screen, it converts it to string
and then returns it. Note that if you call them inside the interactive interpreter just like print0(s)
, it appears they produce the same effect, which may be confusing. However, if you do a = print0(s)
you will see that a
is different. In some languages the last computed value automatically becomes the return value, but with Python that isn't the case for regular functions:
def times_three(x):
x*3
returns None
. However, there are also lambda-functions, for which that is the case:
times_three = lambda x: x*3
times_three(5) #returns 15