Python - view list without assignment

Today I parsed the directory index with a list of paths to zip files using BeautifulSoup and came across an interesting thing. Suppose I would like to take all the href properties of the received tags and put them directly in the queue:

 q = Queue.Queue() [q.put(tag['href']) for tag in soup.findAll('a')] 

I had never encountered a similar situation before when understanding could be used inline without being tied to anything, just to generate another iterator using a regular call. Is this considered bad practice? Is it really "pythonic"? Was there a better single line liner to place all items in line?

+7
source share
4 answers

This has been set many times, for example here and here . But this is an interesting question. The list of concepts is intended to be used for something else.

Other options include

  • use map() is basically the same as your sample
  • use filter() - if your function returns None, you will get an empty list
  • Just a simple for -loop

while a simple loop is the preferred way to do this. In this case, this is semantically correct, all other methods, including understanding lists, the concept of abuse for their side effect.

In Python 3.x, map() and filter() are generators and thus don't do anything until you get to them. Therefore, we need, for example, a list(map(...)) , which makes it even worse.

+8
source

If you think of it as a loop over the list returned by soup.findAll, it will look like this:

 for tag in soup.findAll('a'): q.put(tag['href']) 

This is probably a more "pythonic" form, as "explicit is better than imagined"

+6
source

Probably not the best single-line, but I (personally) will think about it, and not about:

 for tag in soup.findAll('a'): q.put(tag['href']) 

- bad practice. First, one liner will generate a list full of [None] , which is likely to be more inefficient. Secondly, it is not immediately clear what the code does; seeing an understanding of the list usually implies that the resulting list will be used in some way.

+2
source

There are many opinions on this topic, I can only speak from coding conventions in my organization.

There are many ways to influence the cycle, but a key attribute of understanding lists is that they create lists with one element for each in a repeated sequence.

 >>> import Queue >>> q = Queue.Queue() >>> [q.put(item) for item in range(5)] [None, None, None, None, None] >>> 

this unused list is clearly wasteful. Thus, this is a construction, an understanding of a list with an unused return value; It is forbidden to appear in our code base. An explicit loop like the one above, or generated in combination with what it consumes, for example:

 >>> any(q.put(item) for item in xrange(5)) False >>> 

or simply:

 >>> for item in xrange(5): ... q.put(item) ... >>> 

required to pass a review.

+2
source

All Articles