# Storing Multiple Values in Lists¶

## Learning Objectives

• Explain what a list is
• Create and index lists of simple values

Just as a 'for' loop is a way to do operations many times, a list is a way to store many values. Unlike NumPy arrays, lists are built into the language (so we don’t have to load a library to use them). We create a list by putting values inside square brackets:

In [ ]:
odds = [1, 3, 5, 7]
print('odds are:', odds)


We select individual elements from lists by indexing them:

In [ ]:
print('first and last:', odds, odds[-1])


and if we loop over a list, the loop variable is assigned elements one at a time:

In [ ]:
for number in odds:
print(number)


There is one important difference between lists and strings: we can change the values in a list, but we cannot change the characters in a string. For example:

In [ ]:
names = ['Newton', 'Darwing', 'Turing'] # typo in Darwin's name
print('names is originally:', names)
names = 'Darwin' # correct the name
print('final value of names:', names)


works, but:

In [ ]:
name = 'Bell'
name = 'b'


## Ch-Ch-Ch-Changes¶

Data which can be modified in place is called mutable, while data which cannot be modified is called immutable. Strings and numbers are immutable. This does not mean that variables with string or number values are constants, but when we want to change the value of a string or number variable, we can only replace the old value with a completely new value.

Lists and arrays, on the other hand, are mutable: we can modify them after they have been created. We can change individual elements, append new elements, or reorder the whole list. For some operations, like sorting, we can choose whether to use a function that modifies the data in place or a function that returns a modified copy and leaves the original unchanged.

Be careful when modifying data in place. If two variables refer to the same list, and you modify the list value, it will change for both variables! If you want variables with mutable values to be independent, you must make a copy of the value when you assign it.

Because of pitfalls like this, code which modifies data in place can be more difficult to understand. However, it is often far more efficient to modify a large data structure in place than to create a modified copy for every small change. You should consider both of these aspects when writing your code.

There are many ways to change the contents of lists besides assigning new values to individual elements:

In [ ]:
odds.append(11)
print('odds after adding a value:', odds)

In [ ]:
del odds
print('odds after removing the first element:', odds)

In [ ]:
odds.reverse()
print('odds after reversing:', odds)


While modifying in place, it is useful to remember that python treats lists in a slightly counterintuitive way.

If we make a list and (attempt to) copy it then modify in place, we can cause all sorts of trouble:

In [ ]:
odds = [1, 3, 5, 7]
primes = odds
primes += 
print('primes:', primes)
print('odds:', odds)


This is because python stores a list in memory, and then can use multiple names to refer to the same list. If all we want to do is copy a (simple) list, we can use the list() command, so we do not modify a list we did not mean to:

In [ ]:
odds = [1, 3, 5, 7]
primes = list(odds)
primes += 
print('primes:', primes)
print('odds:', odds)


This is different from how variables worked in lesson 1, and more similar to how a spreadsheet works.

## Turn a string into a list

Use a for-loop to convert the string “hello” into a list of letters.
["h", "e", "l", "l", "o"]
NB: you can create an empty list using my_list = []

## Tuples and Excahnges

Use a for-loop to convert the string “hello” into a list of letters.
["h", "e", "l", "l", "o"]
Explain what the overall effect of this code is:
left = 'L'
right = 'R'

temp = left
left = right
right = temp


Compare it to:
 left, right = right, left

Do they always do the same thing? Which does your brain scan better?