Dive Into Python Python for experienced programmers |

## 1.13. Mapping lists

One of the most powerful features of Python is the list comprehension, which provides a compact way of mapping a list into another list by applying a function to each of the elements of the list.

Example 1.31. Introducing list comprehensions

    >>> li = [1, 9, 8, 4]
    >>> [elem*2 for elem in li]
    [2, 18, 16, 8]
    >>> li
    [1, 9, 8, 4]
    >>> li = [elem*2 for elem in li]
    >>> li
    [2, 18, 16, 8]

| To make sense of this, look at it from right to left. `li` is the list you're mapping. Python loops through `li` one element at a time, temporarily assigning the value of each element to the variable `elem`. Python then applies the function ``elem`*2` and appends that result to the returned list.
| Note that list comprehensions do not change the original list.
| It is safe to assign the result of a list comprehension to the variable that you're mapping. There are no racing conditions or any weirdness to worry about; Python constructs the new list in memory, and when the list comprehension is complete, it assigns the result to the variable.

Example 1.32. List comprehensions in `buildConnectionString`

    ["%s=%s" % (k, v) for k, v in params.items()]

First, notice that you're calling the `items` function of the `params` dictionary. This function returns a list of tuples of all the data in the dictionary.

Example 1.33. `keys`, `values`, and `items`

    >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
    >>> params.keys()
    ['server', 'uid', 'database', 'pwd']
    >>> params.values()
    ['mpilgrim', 'sa', 'master', 'secret']
    >>> params.items()
    [('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')]

| The `keys` method of a dictionary returns a list of all the keys. The list is not in the order in which the dictionary was defined (remember, elements in a dictionary are unordered), but it is a list.
| The `values` method returns a list of all the values. The list is in the same order as the list returned by `keys`, so `params.values()[n] == params[params.keys()[n]]` for all values of `n`.
| The `items` method returns a list of tuples of the form `(key, value)`. The list contains all the data in the dictionary.

Now let's see what `buildConnectionString` does. It takes a list, ``params`.`items`()`, and maps it to a new list by applying string formatting to each element. The new list will have the same number of elements as ``params`.`items`()`, but each element in the new list will be a string that contains both a key and its associated value from the `params` dictionary.

Example 1.34. List comprehensions in `buildConnectionString`, step by step

    >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"}
    >>> params.items()
    [('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')]
    >>> [k for k, v in params.items()]
    ['server', 'uid', 'database', 'pwd']
    >>> [v for k, v in params.items()]
    ['mpilgrim', 'sa', 'master', 'secret']
    >>> ["%s=%s" % (k, v) for k, v in params.items()]
    ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']

| Note that we're using two variables to iterate through the `params.items()` list. This is another use of multi-variable assignment. The first element of `params.items()` is `('server', 'mpilgrim')`, so in the first iteration of the list comprehension, `k` will get `'server'` and `v` will get `'mpilgrim'`. In this case we're ignoring the value of `v` and only including the value of `k` in the returned list, so this list comprehension ends up being equivalent to ``params`.`keys`()`. (You wouldn't really use a list comprehension like this in real code; this is an overly simplistic example so you can get your head around what's going on here.)
| Here we're doing the same thing, but ignoring the value of `k`, so this list comprehension ends up being equivalent to ``params`.`values`()`.
| Combining the previous two examples with some simple string formatting, we get a list of strings that include both the key and value of each element of the dictionary. This looks suspiciously like the output of the program; all that remains is to join the elements in this list into a single string.

Further reading

- Python Tutorial discusses another way to map lists using the built-in `map` function.
- Python Tutorial shows how to do nested list comprehensions.