Lists
Overview
Teaching: 20 min
Exercises: 25 minQuestions
How can I store multiple values?
Objectives
Explain why programs need collections of values.
Write programs that create flat lists, index them, slice them, and modify them through assignment and method calls.
A list stores many values in a single structure.
- Doing calculations with a hundred variables called
pressure_001
,pressure_002
, etc., would be at least as slow as doing them by hand. - Use a list to store many values together.
- Contained within square brackets
[...]
. - Values separated by commas
,
.
- Contained within square brackets
pressures = [0.273, 0.275, 0.277, 0.275, 0.276]
print('pressures:', pressures)
pressures: [0.273, 0.275, 0.277, 0.275, 0.276]
Use the built-in function len
to find the length of a list.
print(len(pressures))
5
- Nested functions are evaluated from the inside out, just like in mathematics.
Use an item’s index to fetch it from a list.
- Each position in the list (first, second, etc.) is given a number. This number is called an index.
- Indices are numbered from 0.
- Use the position’s index in square brackets to get the item at that position.
- Note that the words item and element are often used interchangeably.
print('zeroth item of pressures:', pressures[0])
print('fourth item of pressures:', pressures[4])
zeroth item of pressures: 0.273
fourth item of pressures: 0.276
Indexing in Python is from zero
Programming languages like Fortran, MATLAB and R start counting at 1 because that’s what human beings have done for thousands of years. Languages in the C family (including C++, Java, Perl, and Python) count from 0 because it represents an offset from the first value in the array (the second value is offset by one index from the first value). This is closer to the way that computers represent arrays (if you are interested in the historical reasons behind counting indices from zero, you can read Mike Hoye’s blog post). As a result, if we have a Python list with M elements, its indices go from 0 to M-1. It takes a bit of getting used to, but one way to remember the rule is that the index is how many steps we have to take from the start to get the item we want.
Use slicing to fetch multiple items from a list.
- A part of a list is called a list slice. A list slice can be as short as a single item.
- We take a slice by using
[start:stop]
, wherestart
is replaced with the index of the first item we want andstop
is replaced with the index of the item just after the last item we want. - Mathematically, you might say that a slice selects
[start:stop)
. - The difference between stop and start is the slice’s length.
- Taking a slice does not change the contents of the original list. Instead, the slice is a copy of part of the original list.
pressures[0:3]
[0.273, 0.275, 0.277]
Lists’ values can be replaced by assigning to them.
- Use an index expression on the left of assignment to replace a value.
pressures[0] = 0.265
print('pressures is now:', pressures)
pressures is now: [0.265, 0.275, 0.277, 0.275, 0.276]
Appending items to a list lengthens it.
- Use
list_name.append
to add items to the end of a list.
primes = [2, 3, 5]
print('primes is initially:', primes)
primes.append(7)
primes.append(9)
print('primes has become:', primes)
primes is initially: [2, 3, 5]
primes has become: [2, 3, 5, 7, 9]
append
is a method of lists.- Like a function, but tied to a particular object.
- Use
object_name.method_name
to call methods.- Deliberately resembles the way we refer to things in a library.
- We will meet other methods of lists as we go along.
- Use
help(list)
for a preview.
- Use
extend
is similar toappend
, but it allows you to combine two lists. For example:
teen_primes = [11, 13, 17, 19]
middle_aged_primes = [37, 41, 43, 47]
print('primes is currently:', primes)
primes.extend(teen_primes)
print('primes has now become:', primes)
primes.append(middle_aged_primes)
print('primes has finally become:', primes)
primes is currently: [2, 3, 5, 7, 9]
primes has now become: [2, 3, 5, 7, 9, 11, 13, 17, 19]
primes has finally become: [2, 3, 5, 7, 9, 11, 13, 17, 19, [37, 41, 43, 47]]
Note that while extend
maintains the “flat” structure of the list, appending a list to a list makes the result two-dimensional.
Use del
to remove items from a list entirely.
del list_name[index]
removes an item from a list and shortens the list.- Not a function or a method, but a statement in the language.
print('primes before removing last item:', primes)
del primes[4]
print('primes after removing last item:', primes)
primes before removing last item: [2, 3, 5, 7, 9]
primes after removing last item: [2, 3, 5, 7]
The empty list contains no values.
- Use
[]
on its own to represent a list that doesn’t contain any values.- “The zero of lists.”
- Helpful as a starting point for collecting values (which we will see in the next episode).
Lists may contain values of different types.
- A single list may contain numbers, strings, and anything else.
goals = [1, 'Create lists.', 2, 'Extract items from lists.', 3, 'Modify lists.']
Character strings can be indexed and sliced like lists.
- The characters (individual letters, numbers, and so on) in a string are ordered. For example, the string ‘AB’ is not the same as ‘BA’. Because of this ordering, we can treat the string as a list of characters.
- Get characters from a character string using indexes and slices in square brackets.
- The built-in function
len
counts the number of characters in a string.
element = 'carbon'
print('zeroth character:', element[0])
print('sub-string:', element[1:4])
print('length:', len(element))
zeroth character: c
sub-string: arb
length: 6
- But numbers don’t have a length (not even zero).
print(len(52))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-f769e8e8097d> in <module>()
----> 1 print(len(52))
TypeError: object of type 'int' has no len()
Character strings are immutable.
- You cannot change the characters in a string after it has been created.
- Immutable: can’t be changed after creation.
- In contrast, lists are mutable: they can be modified in place.
- Python considers the string to be a single value with parts, not a collection of values.
element[0] = 'C'
TypeError: 'str' object does not support item assignment
- Lists and character strings are both collections.
Indexing beyond the end of the collection is an error.
- Python reports an
IndexError
if we attempt to access a value that doesn’t exist.- This is a kind of runtime error.
- Cannot be detected as the code is parsed because the index might be calculated based on data.
print('99th element of element is:', element[99])
IndexError: string index out of range
Fill in the Blanks
Fill in the blanks so that the program below produces the output shown.
values = ____ values.____(1) values.____(3) values.____(5) print('first time:', values) values = values[____] print('second time:', values)
first time: [1, 3, 5] second time: [3, 5]
Solution
values = [] values.append(1) values.append(3) values.append(5) print('first time:', values) values = values[1:] print('second time:', values)
How Large is a Slice?
If ‘low’ and ‘high’ are both non-negative integers, how long is the list
values[low:high]
?Solution
The list
values[low:high]
hashigh - low
elements. For example,values[1:4]
has the 3 elementsvalues[1]
,values[2]
, andvalues[3]
. Note that the expression will only work ifhigh
is less than the total length of the listvalues
.
From Strings to Lists and Back
Given this:
print('string to list:', list('tin')) print('list to string:', ''.join(['g', 'o', 'l', 'd']))
['t', 'i', 'n'] 'gold'
- Explain in simple terms what
list('some string')
does.- What does
'-'.join(['x', 'y'])
generate?Solution
list('some string')
“splits” a string into a list of its characters.x-y
Working With the End
What does the following program print?
element = 'helium' print(element[-1])
- How does Python interpret a negative index?
- If a list or string has N elements, what is the most negative index that can safely be used with it, and what location does that index represent?
- If
values
is a list, what doesdel values[-1]
do?- How can you display all elements but the last one without changing
values
? (Hint: you will need to combine slicing and negative indexing.)Solution
The program prints
m
.
- Python interprets a negative index as starting from the end (as opposed to starting from the beginning). The last element is
-1
.- The last index that can safely be used with a list of N elements is element
-N
, which represents the first element.del values[-1]
removes the last element from the list.values[:-1]
Stepping Through a List
What does the following program print?
element = 'fluorine' print(element[::2]) print(element[::-1])
- If we write a slice as
low:high:stride
, what doesstride
do?- What expression would select all of the even-numbered items from a collection?
Solution
The program prints
furn eniroulf
stride
is the step size of the slice- The slice
1::2
selects all even-numbered items from a collection: it starts with element1
(which is the second element, since indexing starts at0
), goes on until the end (since noend
is given), and uses a step size of2
(i.e., selects every second element).
Slice Bounds
What does the following program print?
element = 'lithium' print(element[0:20]) print(element[-1:3])
Solution
lithium
Sort and Sorted
What do these two programs print? In simple terms, explain the difference between
sorted(letters)
andletters.sort()
.# Program A letters = list('gold') result = sorted(letters) print('letters is', letters, 'and result is', result)
# Program B letters = list('gold') result = letters.sort() print('letters is', letters, 'and result is', result)
Solution
Program A prints
letters is ['g', 'o', 'l', 'd'] and result is ['d', 'g', 'l', 'o']
Program B prints
letters is ['d', 'g', 'l', 'o'] and result is None
sorted(letters)
returns a sorted copy of the listletters
(the original listletters
remains unchanged), whileletters.sort()
sorts the listletters
in-place and does not return anything.
Copying (or Not)
What do these two programs print? In simple terms, explain the difference between
new = old
andnew = old[:]
.# Program A old = list('gold') new = old # simple assignment new[0] = 'D' print('new is', new, 'and old is', old)
# Program B old = list('gold') new = old[:] # assigning a slice new[0] = 'D' print('new is', new, 'and old is', old)
Solution
Program A prints
new is ['D', 'o', 'l', 'd'] and old is ['D', 'o', 'l', 'd']
Program B prints
new is ['D', 'o', 'l', 'd'] and old is ['g', 'o', 'l', 'd']
new = old
makesnew
a reference to the listold
;new
andold
point towards the same object.
new = old[:]
however creates a new list objectnew
containing all elements from the listold
;new
andold
are different objects.
Identifying Item Errors
- Read the code below and try to identify what the errors are without running it.
- Run the code, and read the error message. What type of error is it?
- Fix the error.
seasons = ['Spring', 'Summer', 'Fall', 'Winter'] print('My favorite season is ', seasons[4])
Solution
seasons = ['Spring', 'Summer', 'Fall', 'Winter'] print('My favorite season is ', seasons[3])
Key Points
A list stores many values in a single structure.
Use the built-in function
len
to find the length of a list.Use an item’s index to fetch it from a list.
Use slicing to fetch multiple items from a list.
Lists’ values can be replaced by assigning to them.
Appending items to a list lengthens it.
Use
del
to remove items from a list entirely.The empty list contains no values.
Lists may contain values of different types.
Character strings can be indexed and sliced like lists.
Character strings are immutable.
Indexing beyond the end of the collection is an error.