The range function returns a list in Python 2, and in iterator in Python 3. We are concerned with Python 2.

```
my_range = range(5)
print my_range # [0, 1, 2, 3, 4]
```

Notice the list does not contain the number 5? However, there are five elements in the list. The above usage with only one argument defaults to 0 as the starting value.

When a starting value is specified, then it takes the place of the default.

`range(5) == range(0, 5)`

Say we want a list of numbers from 1 to 10. It is a common assumption that it would be written like,

`range(1, 10)`

but that would be wrong since we know that the last value of the list will be `9`

and not `10`

. To determine how many elements will be in the list, subtract the start value from the end value.

`10 - 1 == 9`

so the correct expression will then be,

```
range(1, 11)
# 11 - 1 == 10
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

Now because of the way `range`

works it is great for iterating lists which are zero-indexed.

`for i in range(len(numbers)):`

`i`

will be `0`

to start, and will end at `len(numbers) minus 1`

which will be the correct final index of the list.