Python: Comprehensions
Tags: python, comprehensions, snippets, javascript
Published: 2021-08-06 14:09:27

Comprehensions (and list comprehensions in particular) are probably the feature I love the most coming from JavaScript to Python. It enables you to write concise code for something you do very often: Iterating over a list, modifying the data a bit ("data massaging") and returning a list with the new entries.

**One thing to note:** List comprehension load the entire output into memory so this should only be used for small to medium-sized lists. In cases of big lists, use generators instead.

**Basic Syntax (for lists):**

```
[expression for item in iterable if conditional]
```

If you want to try the instructions below you can fire up the Python REPL. If you have Python installed run `python` in your terminal. Any Python code that starts with `>>>` symbols indicated that it was typed into a REPL.
To try out the JavaScript snippets you could use [Quokka.js](https://quokkajs.com/) in your editor.

## Examples

Iterating over the array and giving out the length of the word itself into a new list:

```js
const names = ["James", "Naomi", "Amos", "Alex", "Bobbie", "Clarissa"]
const len_names = names.map((name) => name.length)
console.log(len_names)
// [ 5, 5, 4, 4, 6, 8 ]
```

```py
>>> names = ["James", "Naomi", "Amos", "Alex", "Bobbie", "Clarissa"]
>>> len_names = [len(name) for name in names]
>>> print(len_names)
[5, 5, 4, 4, 6, 8]
```

Skipping the first item & last item (by index) and creating a list of dictionaries:

```js
const names = ["James", "Naomi", "Amos", "Alex", "Bobbie", "Clarissa"]
const names_list = names
  .filter((_, id) => id !== 0 && id !== names.length - 1)
  .map((name) => ({ name, length: name.length }))
console.log(names_list)
// [ { name: 'Naomi', length: 5 }, { name: 'Amos', length: 4 }, { name: 'Alex', length: 4 }, { name: 'Bobbie', length: 6 } ]
```

```py
>>> names = ["James", "Naomi", "Amos", "Alex", "Bobbie", "Clarissa"]
>>> names_list = [{ "name": name, "length": len(name) } for idx, name in enumerate(names) if idx != 0 and idx != len(names)-1]
>>> print(names_list)
[{'name': 'Naomi', 'length': 5}, {'name': 'Amos', 'length': 4}, {'name': 'Alex', 'length': 4}, {'name': 'Bobbie', 'length': 6}]
```

Tuple unpacking:

```js
const students = [
  ["James", 16],
  ["Naomi", 20],
]
const nameWithAge = students.map((s) => [s[0].length + s[1], ...s])
console.log(nameWithAge)
// [ [ 21, 'James', 16 ], [ 25, 'Naomi', 20 ] ]
```

```py
>>> students = [("James", 16), ("Naomi", 20)]
>>> nameWithAge = [[len(s[0])+s[1], *s] for s in students]
>>> print(nameWithAge)
[[21, 'James', 16], [25, 'Naomi', 20]]
```

Creating a list of characters from a string:

```js
const myName = "LekoArts"
const arr = [...myName]
console.log(arr)
// [ 'L', 'e', 'k', 'o', 'A', 'r', 't', 's' ]
```

```py
>>> my_name = 'LekoArts'
>>> arr = [l for l in my_name]
>>> print(arr)
['L', 'e', 'k', 'o', 'A', 'r', 't', 's']
```

Reversing strings in a tuple and returning them as a list:

```js
const words = ["kayak", "LekoArts", "radar", "python"]
const reversed = words.map((word) => word.split("").reverse().join(""))
console.log(reversed)
// [ 'kayak', 'strAokeL', 'radar', 'nohtyp' ]
```

```py
>>> words = ("kayak", "LekoArts", "radar", "python")
>>> reversed = [word[::-1] for word in words]
>>> print(reversed)
['kayak', 'strAokeL', 'radar', 'nohtyp']
```

You can also nest comprehensions. Here's a 3 by 3 identity matrix:

```py
>>> matrix = [[1 if item_idx == row_idx else 0 for item_idx in range(0, 3)] for row_idx in range(0, 3)]
>>> print(matrix)
[[1, 0, 0], [0, 1, 0], [0, 0, 1]]
```