python - list comprehension without assignment
There are many opinions on this thread, I can only speak from coding conventions at my organization.
there are many ways to affect a loop, but a key attribute of list comprehensions is that they create lists, with one item for each in the iterated over sequence.
>>> import Queue
>>> q = Queue.Queue()
>>> [q.put(item) for item in range(5)]
[None, None, None, None, None]
>>>
this unused list is obviously wasteful. As such, this construction, a list comprehension with unused return value; is forbidden from appearing in our code base. An explicit loop like above, or a generated combined with something that consumes it, for instance:
>>> any(q.put(item) for item in xrange(5))
False
>>>
or just:
>>> for item in xrange(5):
... q.put(item)
...
>>>
is required to pass review.
This has been asked many times, e.g., here and here. But it's an interesting question, though. List comprehensions are meant to be used for something else.
Other options include
- use
map()
- basically the same as your sample - use
filter()
- if your function returns None, you will get an empty list - Just a plain
for
-loop
while the plain loop is the preferable way to do it. It is semantically correct in this case, all other ways, including list comprehension, abuse concepts for their side-effect.
In Python 3.x, map()
and filter()
are generators and thus do nothing until you iterate over them. So we'd need, e.g., a list(map(...))
, which makes it even worse.
If you think of it as a loop over the list returned by soup.findAll it would look like this:
for tag in soup.findAll('a'):
q.put(tag['href'])
This is probably the more 'pythonic' form as 'explicit is better than implict'