# Lists¶

If we'd like to store more than one value in a single variable, we can use lists. For example, here are the average gross annual earnings for anesthesiologists, non-doctors, cardiologists, pediatricians, and family doctors, respectively (from https://www.cma.ca/Assets/assets-library/document/en/advocacy/Anesthesiology-e.pdf and similar sources on cma.ca)

361.681
62.15
396.105
284.600
249.154

We can store the data in Python as followd:

In [2]:
gross_earnings = [361.681, 62.15, 396.105,  284.600, 249.154]


We enclose the data in square brackets, and element of the list is separated by commas. We access the elements by their index -- the order of the element in the list, starting from 0.

In [3]:
gross_earnings[0]

Out[3]:
361.681
In [4]:
gross_earnings[1]

Out[4]:
62.15
In [5]:
gross_earnings[4]

Out[5]:
249.154

Note that, since there are 5 elements in the list and we start from 0, we only have indices 0, 1, 2, 3, and 4. The following produces an error:

In [6]:
gross_earnings[5]

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-6-57b472f13599> in <module>()
----> 1 gross_earnings[5]

IndexError: list index out of range

The reason we get an error is that there is no element number 5 (counting from 0) in the list gross_earnings.

You can treat expressions like gross_earnings[2] like any other value (like 5, or the variable memory). For example:

In [8]:
.6*(gross_earnings[2] + 500)

Out[8]:
537.663
In [9]:
gross_earnings[1] = gross_earnings[1]*10
print(gross_earnings[1])

621.5


You can access elements not just by typing in numbers, but also by using variables as indices:

In [11]:
i = 2
print(gross_earnings[i])

396.105

In [17]:
i = 3-2
print(gross_earnings[i])

621.5


## Length of a list, and the last element of a list¶

There is a way to obtain the length of a list: we use len():

In [16]:
len(gross_earnings)

Out[16]:
5

We got 5, because 5 is the number of elements in gross_earnings. How to get the last element using that? If we have 5 elements in total, that means that the indices: 0, 1, 2, 3, 4 go up to 4 = 5 - 1 (because we started from 0.)

That means that the last element of the list L (to pick a generic name will be L[len(L)-1]

In [19]:
L = [4, 5, 6]
print("Length of L:", len(L))
print("The index of the last element of L:", len(L)-1)
print("The last element of L:", L[len(L)-1])

Length of L: 3
The index of the last element of L: 2
The last element of L: 6


In Python, there is a shorthand for len(L)-1. Instead, we can just write (but only inside the square brackets) -1:

In [20]:
print(L[-1])  #same as L[len(L)-1]
print(L[-2])  #same as L[len(L)-2]

6
5


You can think of the index -1 as "first from the right end" (but note that we ordinarily start counting the indices from 0, whereas if we're counting form the end, we start from -1).

# Iteration and Loops¶

## Printing out all the earnings¶

Suppose we want to print out all the earnings in gross_earnings. In other words, we want to print gross_earnings[0], then gross_earnings[1], then gross_earnings[2] and so on, but we don't know the size of gross_earnings in advance.

In other words, we want to print out gross_earnings[0]
gross_earnings[1]
gross_earnings[2]
gross_earnings[3]
...
gross_earnings[len(gross_earnings)-1]

Or in other words, we want to print out gross_earnings[i] for i == 0
gross_earnings[i] for i == 1
gross_earnings[i] for i == 2
gross_earnings[i] for i == 3
...
gross_earnings[] for i == len(gross_earnings)-1

There is a way to do this in Python.

## Loops¶

You can print out all the numbers from 0 to 4 (inclusive) as follows:

In [21]:
for i in range(5):
print(i)

0
1
2
3
4


What happens here is that the line print(i) is repeated for i = 0, i = 1, ..., i = (5-1), so we first print 0, then 1, ..., then 4.

Note that since we're starting from 0 and go up until 5-1, we repeat the line exactly 5 times.

This construct is called a for-loop.

In general, for i in range(N):

will repeate the BLOCK N times, for i = 0, 1, 2, ..., N-1.

The BLOCK can be more than one line long, of course.

## Printing out a list¶

Let's use a for-loop to print out the list gross_earnings. We already have all the ingredients: we know how to get i to be 0, then 1, then 2, ..., then len(gross_earnings)-1, and we know how to get the i-th element of gross_earnings. We just need to combine those together.

In [24]:
for i in range(len(gross_earnings)):
print("Element", i, ":", gross_earnings[i])


Element 0 : 361.681
Element 1 : 621.5
Element 2 : 396.105
Element 3 : 284.6
Element 4 : 249.154


## Only printing some of the elements¶

Suppose we only want to print the elements of gross_earnings that are no smaller than 100 (for marketing purposes, say.) How to do that?

By now, we know how to print something conditionally:

In [25]:
hours_slept = 7
if hours_slept < 8:
print("PRESS SNOOZE BUTTON")

PRESS SNOOZE BUTTON

In [27]:
hours_slept = 9
if hours_slept < 8:
print("PRESS SNOOZE BUTTON")   #Will not get executed for hours_slept == 9
#No output at all


Let's use the same idea, but inside the for-loop.

In [29]:
gross_earnings = [361.681, 62.15, 396.105,  284.600, 249.154]
for i in range(len(gross_earnings)):
if gross_earnings[i] >= 100.0:
print(gross_earnings[i])


361.681
396.105
284.6
249.154


Let's trace this.

In [30]:
from IPython.display import YouTubeVideo

Out[30]:

## Computing the sum of a list¶

Suppose we want to compute the sum of all the values in a list. Here's the ides: we'll set up a variable s, and we'll keep adding adding elements to it.

So at first, s will be 0. Then we'll add gross_earnings[0] to it, and s will become gross_earnings[0].
Then we'll add gross_earnings[1] to it, and s will become gross_earnings[0] + gross_earnings[1].
...
Then we'll add gross_earnings[len(gross_earnings)-1] to it, and s will become the sum of all the elements in gross earnings.

Here is how to express this in Python.

In [32]:
gross_earnings = [361.681, 62.15, 396.105,  284.600, 249.154]
s = 0
for i in range(len(gross_earnings)):
s = s + gross_earnings[i]
print("At iteration", i, "s = ", s)

print("Final s:", s)

At iteration 0 s =  361.681
At iteration 1 s =  423.83099999999996
At iteration 2 s =  819.9359999999999
At iteration 3 s =  1104.536
At iteration 4 s =  1353.69
Final s: 1353.69


We didn't have to print out the intermediate values of s, of course. We just did that for illustration purposes.

## P1: Iteration and Accumulation¶

### Compute the average of a list of values¶

Once we know the sum of a list, computing the average is easy: all we need to do is divide the sum by the number of elements. And the number of elements of the list gross_earnings is len(gross_earnings).

In [33]:
gross_earnings = [361.681, 62.15, 396.105,  284.600, 249.154]
s = 0
for i in range(len(gross_earnings)):
s = s + gross_earnings[i]
print("At iteration", i, "s = ", s)

print("Final s:", s)
print("Average:", s/len(gross_earnings))

At iteration 0 s =  361.681
At iteration 1 s =  423.83099999999996
At iteration 2 s =  819.9359999999999
At iteration 3 s =  1104.536
At iteration 4 s =  1353.69
Final s: 1353.69
Average: 270.738


(We just added one more line to the program that computed the sum.)

## P2: Conditional + Loops¶

### Compute the average of gross_earnings, but exclude any earnings that are not within the range from 100 to 300¶

The first step here is to compute the sum of all the earnings between 100 and 300 in gross_earnings. We already did something very similar to this when we only printed out earnings that were at or above 100. Let's use the same trick here.

In [6]:
gross_earnings = [361.681, 62.15, 396.105,  284.600, 249.154]

s = 0
for i in range(len(gross_earnings)):
if gross_earnings[i] > 300:
print("i =", i, ". gross_earnings[i] = ", gross_earnings[i], ". Too high, excluded")
elif gross_earnings[i] >= 100:
print("i =", i, ". gross_earnings[i] = ", gross_earnings[i])
s = s + gross_earnings[i]
else:
print("i =", i, ". gross_earnings[i] = ", gross_earnings[i], ". Too low, excluded")

print("The sum of earnings in the 100.300 range is", s)

i = 0 . gross_earnings[i] =  361.681 . Too high, excluded
i = 1 . gross_earnings[i] =  62.15 . Too low, excluded
i = 2 . gross_earnings[i] =  396.105 . Too high, excluded
i = 3 . gross_earnings[i] =  284.6
i = 4 . gross_earnings[i] =  249.154
The sum of earnings in the 100.300 range is 533.754


So far, so good, but we want the average. That means that we need to figure out how many elements we have added into s. Here's an idea for how to do this: in addition to the variable s, have another variable, called count. We will add 1 to count every time we add an element into s.

Let's explore this idea more, and come up with a program that counts the number of elements in a list that are within a certain range.

In [39]:
from IPython.display import YouTubeVideo

Out[39]:

Note that in the video, I forgot to set count to 0 in the beginning! For reference, the code is

In [40]:
L = [5, 6, 10, 2, 7]
count = 0
for i in range(len(L)):
if 5 <= L[i] <= 8:
count = count + 1
print("The number of elements of L that are in the range 5..8:", count)

The number of elements of L that are in the range 5..8: 3


Then, after we're done adding elements into s, we will be able to look at count and know exactly how many elements we've added into s, since every time we've added an element into s, we've increased count by one, so count will be exactly as large as the number of elements added into s!

In [7]:
gross_earnings = [361.681, 62.15, 396.105,  284.600, 249.154]

s = 0
count = 0
for i in range(len(gross_earnings)):
if gross_earnings[i] > 300:
print(gross_earnings[i], ": Too high, excluded")
elif gross_earnings[i] >= 100:
s = s + gross_earnings[i]
count = count + 1
else:
print(gross_earnings[i], ": Too low, excluded")

print("The sum of earnings in the 100..300 range is", s)
print("The number of elements added into s is", count)
print("The average of earnings in the 100..300 range is", s/count)

361.681 : Too high, excluded
62.15 : Too low, excluded
396.105 : Too high, excluded
The sum of earnings in the 100..300 range is 533.754
The number of elements added into s is 2
The average of earnings in the 100..300 range is 266.877


We are using the same idea as above for computing the count, but are using a slightly different if-statement.

In [8]:
%%javascript
\$.getScript('https://kmahelona.github.io/ipython_notebook_goodies/ipython_notebook_toc.js')