Whenever you see this pattern to create a list of items:

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

You can replace it with a list comprehension, which takes the form of:

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

This:

```
t = []
for i in range(10):
t.append(i * i)
```

Can be replaced with:

`t = [(i * i) for `**i** in range(10)]

Notice how the variable used to iterate over the collection is made available for calculating the expression which will be added to our resulting list.

`squares = [x * x for `**x** in [0, -1, -2, 3, 4]]
print(squares)
# **outputs**:
[0, 1, 4, 9, 16]

We can of course, add an *if expression* to the list comprehension, to filter the collection:

`even = [x for x in range(10) `**if x % 2 == 0**]
odd = [x for x in range(10) **if x % 2 != 0**]
print(even)
print(odd)
# **outputs**:
[0, 2, 4, 6, 8]
[1, 3, 5, 7, 9]

We can also **enumerate** our collection to make use of the **index** in our *if condition*, and/or *expression*:

```
even = [x * i for i, x in enumerate(range(10)) if (i > 4) and (x % 2 == 0)]
odd = [x * i for i, x in enumerate(range(10)) if (i > 4) and (x % 2 != 0)]
print(even)
print(odd)
#
```**outputs**:
[36, 64]
[25, 49, 81]

Finally, here is an example where I ignore the value and generate a random number three times:

```
from random import randint
def roll_die():
return [
```**randint(1, 6)** for i in range(3)]
# generate footballer attributes
strength = sum(roll_die())
stamina = sum(roll_die())
morale = sum(roll_die())
print(f'str: {strength}')
print(f'sta: {stamina}')
print(f'mor: {morale}')
# **outputs**:
str: 8
sta: 15
mor: 13