The key to understanding list comprehensions is that they’re just for -loops over a collection expressed in a more terse and compact syntax. Let’s take the following list comprehension as an example:

>>> squares = [x * x for x in range(10)]

It computes a list of all integer square numbers from 0 to 9:

>>> squares [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

If we wanted to build the same list using a plain for -loop we’d probably write something like this:

>>> squares = [] >>> for x in range(10): ... squares.append(x * x)

That’s a pretty straightforward loop, right? If you try and generalize some of this structure you might end up with a template similar to this:

(values) = [ (expression) for (value) in (collection) ]

The above list comprehension is equivalent to the following plain for -loop:

(values) = [] for (value) in (collection): (values).append( (expression) )

Again, a fairly simple cookiecutter pattern you can apply to most for loops. Now there’s one more useful element we need to add to this template, and that is element filtering with conditions .

List comprehensions can filter values based on some arbitrary condition that decides whether or not the resulting value becomes a part of the output list. Here’s an example:

>>> even_squares = [x * x for x in range(10) if x % 2 == 0]

This list comprehension will compute a list of the squares of all even integers from 0 to 9.

If you’re not familiar with what the modulo ( % ) operator does―it returns the remainder after division of one number by another. In this example the % -operator gives us an easy way to test if a number is even by checking the remainder after we divide the number by 2.

>>> even_squares [0, 4, 16, 36, 64]

Similarly to the first example, this new list comprehension can be transformed into an equivalent for -loop:

even_squares = [] for x in range(10): if x % 2 == 0: vals.append(x)

Let’s try and generalize the above list comprehension to for-loop transform again. This time we’re going to add a filter condition to our template to decide which values end up in the resulting list.

Here’s the list comprehension template:

values = [expression for value in collection if condition]

And we can transform this list comprehension into a for -loop with the following pattern:

vals = [] for value in collection: if condition: vals.append(expression)

Again, this is a straightforward transformation―we simply apply our cookiecutter pattern again. I hope this dispelled some of the “magic” in how list comprehensions work. They’re really quite a useful tool.

Before you move on I want to point out that python not only supports list comprehensions but also has similar syntax for sets and dictionaries .

Here’s what a set comprehension looks like:

>>> { x * x for x in range(-9, 10) } set([64, 1, 36, 0, 49, 9, 16, 81, 25, 4])

And this is a dict comprehension :

>>> { x: x * x for x in range(5) } {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Both are useful tools in practice. There’s one caveat to Python’s comprehensions―as you get more proficient at using them it becomes easier and easier to write code that’s difficult to read. If you’re not careful you might have to deal with monstrous list, set, dict comprehensions soon. Remember, too much of a good thing is usually a bad thing.

After much chagrin I’m personally drawing the line at one level of nesting for comprehensions. I found that in most cases it’s better (as in “more readable” and “easier to maintain”) to use for -loops beyond that point.

1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责；
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性，不作出任何保证或承若；
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。