`[]`

¶*A review*

In [1]:

```
fruits = ['plums', 'peaches', 'pears', 'persimmons']
fruits[0]
```

Out[1]:

'plums'

In [2]:

```
fruits[1]
```

Out[2]:

'peaches'

In [3]:

```
fruits[3]
```

Out[3]:

'persimmons'

In [4]:

```
fruits[4]
```

In [5]:

```
fruits = ['plums', 'peaches', 'pears', 'persimmons']
fruits[-1]
```

Out[5]:

'persimmons'

In [6]:

```
fruits[-3]
```

Out[6]:

'peaches'

In [9]:

```
fruits[-4]
```

Out[9]:

'plums'

In [11]:

```
fruits[len(fruits)-1], fruits[-1]
```

Out[11]:

('persimmons', 'persimmons')

`range`

¶In [15]:

```
for i in range(12):
print(i)
```

0 1 2 3 4 5 6 7 8 9 10 11

In [16]:

```
range(5)
```

Out[16]:

range(0, 5)

In [17]:

```
list(range(5))
```

Out[17]:

[0, 1, 2, 3, 4]

In [18]:

```
fruits = ['apples', 'apricots', 'avacados']
for index in range(len(fruits)):
print(fruits[index])
print()
# Same as
for fruit in fruits:
print(fruit)
```

apples apricots avacados apples apricots avacados

In [19]:

```
list(range(4, 12))
```

Out[19]:

[4, 5, 6, 7, 8, 9, 10, 11]

In [20]:

```
list(range(4, 12, 2))
```

Out[20]:

[4, 6, 8, 10]

What python expression using `range`

would you use to create the following sequences?

`1, 2, 3, 4, 5`

`0, 2, 4, 6, 8`

`-6, -3, 0, 3, 6`

`5, 4, 3, 2`

In [21]:

```
list(range(1, 6))
```

Out[21]:

[1, 2, 3, 4, 5]

In [23]:

```
list(range(0, 10, 2))
```

Out[23]:

[0, 2, 4, 6, 8]

In [24]:

```
list(range(-6, 9, 3))
```

Out[24]:

[-6, -3, 0, 3, 6]

In [25]:

```
list(range(1.1, 6.6, 1.1))
```

In [26]:

```
list(range(5, 1, -1))
```

Out[26]:

[5, 4, 3, 2]

In [27]:

```
bears = ['brown','black','polar','koala']
bears
```

Out[27]:

['brown', 'black', 'polar', 'koala']

In [28]:

```
bears[3]
```

Out[28]:

'koala'

In [29]:

```
bears[3] = 'panda'
```

In [30]:

```
bears[3]
```

Out[30]:

'panda'

In [31]:

```
bears
```

Out[31]:

['brown', 'black', 'polar', 'panda']

How do these functions compare?

In [33]:

```
def large_value_of_two(items):
"""Replace 2 with something bigger (like 5)"""
new_items = []
for item in items:
if item == 2:
item = 5
new_items.append(item)
return new_items
```

In [34]:

```
def large_value_of_2(items):
"""Replace 2 with something bigger (like 5)"""
for i in range(len(items)):
if items[i] == 2:
items[i] = 5
```

In [35]:

```
numbers = [1, 2, 3, 4]
print("Numbers before:", numbers)
first_return = large_value_of_two(numbers)
print("Numbers after:", numbers)
print("large_value_of_two returned:", first_return)
print()
print("Numbers before:", numbers)
second_return = large_value_of_2(numbers)
print("Numbers after:", numbers)
print("large_value_of_2 returned:", second_return)
```

Just because a function **can** change a list doesn't mean it **should**.

**immutability** whenever possible: only change inputs when there is a clear advantage over making a copy

Clearly define and document the intent of your functions.

- does a function
**change**the input or only**read**the input?

`edits.py`

¶`score_board.py`

¶- indexing lists with
`[]`

`range`

- list mutability