EDIT: stupid logic of mine got ahead of me. The none are just the returns from the comprehension call. Ok, I'm running some tests in python, and I ran into a bit of a difference in execution orders, which leads me to an understanding of how it is implemented, but I'd like to run it by you fine people to see if I'm right or there is more to it. Consider this code:
>>> a = ["a","b","c","d","e"]
>>> def test(self,arg):
... print "testing %s" %(arg)
... a.pop()
...
>>>[test(elem) for elem in a]
testing a
testing b
testing c
[None, None, None]
>>> a
['a', 'b']
#now we try another syntax
>>> a = ["a","b","c","d","e"]
>>> for elem in a:
... print "elem is %s"%(elem)
... test(elem)
...
elem is a
testing a
elem is b
testing b
elem is c
testing c
>>> a
['a', 'b']
>>>
Now this tells me that the for elem in a: gets the next iteratable element then applies the body, whereas the comprehension somehow calls the function on each element of the list before actually executing the code in the function, so modifying the list from the function ( pop) leads to the ]none, none, none]
Is this right? what is happening here?
thanks
Your test
function has no return
statement, thus using it in a list comprehension results in a list of None
s. The interactive python prompt prints out whatever the last statement returns.
Example:
>>> def noop(x): pass
...
>>> [noop(i) for i in range(5)]
[None, None, None, None, None]
So really there's no difference in how the list comprehension and for
loop in your question work.
>>> a = ["a","b","c","d","e"]
>>> i = iter(a)
>>> next(i)
'a'
>>> a.pop()
'e'
>>> next(i)
'b'
>>> a.pop()
'd'
>>> next(i)
'c'
>>> a.pop()
'c'
>>> next(i)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With