import sandbox_widget
import codelens_widget21 Lists
This chapter is about lists and dictionaries that are Python values that can contain other Python values. Lists and dictionaries let you build relationships between values, which is what data structures represent.
Lists
For many kinds of data, the order of things is important. Just like the order of characters is important for the meaning of the text in a string, we sometimes want to specify the order of other things because the relative order of items in the list has some meaning. It could be a grocery list where you have listed the things to buy in the order you get to them in the supermarket. This is where Python lists are helpful. When you print a list, it nicely shows all the values it contains.
%%sandbox
grocery_list = ["salad", "canned beans", "milk", 'beer', 'candy']
print(grocery_list)Unlike strings that can only store the order of characters, lists can contain any kind of values, and you can mix different types of values in any way you like. Here is a list that contains an integer, a boolean, a string, and a list:
%%sandbox
mixed_list = [42, True, 'programming', [1, 2, 3] ]By now, you have probably guessed you will make a list with two square brackets. Between them, you can put values with commas in between. A list is a container of other values, and the value of the list itself does not depend on the values it contains. This makes sense. Otherwise, an empty list would not have a value:
%%sandbox
my_list = []You can add single values to the end of a list using the append method of lists. Try it out:
%%sandbox
desserts = []
print(desserts)
desserts.append('Crepe suzette')
print(desserts)
desserts.append('Tiramisu')
print(desserts)
desserts.append('Creme brulee')
print(desserts)If you have a list you want to add to the end of another list, you use the extend method. Run it:
%%sandbox
desserts = ['Crepe suzette', 'Tiramisu', 'Creme brulee']
cheeses = ['Gorgonzola', 'Emmentaler', 'Camembert']
desserts.extend(cheeses)
print(desserts)Notice how append and extend modifies the existing list instead of producing a new list with the added element.
Exercise 21-1
Do you think this will work? Run it and see.
%%sandbox
cheeses = ['Gorgonzola',
'Emmentaler',
'Camembert']
print(cheeses)Surprised? Code inside parentheses, brackets, and braces can span several lines, sometimes making your code easier to read.
Exercise 21-2
You use the’ in’ operator to test if a value is in a list. Try this:
%%sandbox
desserts = ['Crepe suzette', 'Tiramisu', 'Creme brulee', 'Gorgonzola', 'Emmentaler', 'Camembert']
print('Tiramisu' in desserts)
print('Meatloaf' in desserts)Exercise 21-3
You can concatenate two lists to produce a new joined list. Make sure you figure out how this works before you try it. Then, experiment with changing the lists. Can you concatenate two empty lists?
%%sandbox
some_list = [1, 2, 3]
another_list = [7, 8, 9]
merged_list = some_list + another_list
print(merged_list)This is yet another example of how the functionality of Python objects lets them “know” how to behave under different circumstances, such as when adding two objects (see Section 20.0.0.11).
Exercise 21-4
What do you think is printed here? Make sure you figure out how you think this works before you try it out. What does the append method return?
%%sandbox
my_list = []
x = my_list.append(7)
print(x)
print(my_list)Indexing and slicing lists
Now you know how to make lists, but to work with the values in lists, you must also know how to access the individual values a list contains. Fortunately, indexing lists work just like indexing strings: Each value in a list is identified by an index exactly like each character in a string:
%%sandbox
numbers = [7, 4, 6, 2, 8, 1]
print("first value is", numbers[0])
print("second value is", numbers[1])
print("third value is", numbers[2])Notice that the function len can also compute the length of a list. So you also get the last value in a list like this:
%%sandbox
numbers = [7, 4, 6, 2, 8, 1]
last_index = len(numbers)-1
print("Last element is", numbers[last_index])If you want a sub-list of values from a list (we also call that a slice), you specify a start index and an end index separated by a colon, just like with strings:
%%sandbox
numbers = [7, 4, 6, 2, 8, 1]
print(numbers[1:4])When you run that, you can see that numbers[1:4] is substituted for [4, 6, 2], so the slicing operation produces a new list of the specified values.
Exercise 21-5
What do these two expressions reduce to?
%%sandbox
[11, 12, 13, 14, 15, 16, 17][2]Exercise 21-6
What is printed here? Do all the substitution and reduction steps and compare them to the exercise above.
%%sandbox
l = [11, 12, 13, 14, 15, 16, 17]
print(l[2])Exercise 21-7
What is printed here? Do all the substitution and reduction steps — and do them twice. Next week, you will be happy you did.
%%sandbox
numbers = [1,2,3]
i = 0
print(numbers[i])
i = 1
print(numbers[i])
i = 2
print(numbers[i])Exercise 21-8
What do you think happens here? Make up your mind and try out the code below:
%%sandbox
l = [11, 12, 13, 14, 15, 16, 17]
l[4] = "Donald"
print(l)Were you surprised by what happened? Compare to Section 20.0.0.15. Lists are not immutable like strings, and you can replace values by assigning a new value to an index in the list.
Exercise 21-9
With your knowledge of slicing, what do you think is printed below:
%%sandbox
l = [11, 12, 13, 14, 15, 16, 17]
print(l[:3])
print(l[3:])
print(l[:])Exercise 21-10
What do you think happens when you specify an index that does not correspond to a value in the list? Decide, then run it:
%%sandbox
l = [11, 12, 13, 14, 15, 16, 17]
print(l[7])Read and understand the error message. Does it ring a bell?
Then ask the assistant to explain the error and to tell you the largest index this list will accept. Check that number by running it, and run one larger too. An answer that is off by one is the most likely way for the assistant to be wrong here, and it is also the easiest to catch.
Exercise 21-11
Do you also get an error when you specify a slice where the end is too high? Try it out:
%%sandbox
l = [11, 12, 13, 14, 15, 16, 17]
print(l[4:99])I guess that is also worth remembering.
Exercise 21-12
Which value in a list named l does this expression reduce to?
l[len(l)-1]Exercise 21-13
If you do not like Emmentaler, you can delete it. What does the del keyword do?
%%sandbox
cheeses = ['Gorgonzola', 'Emmentaler', 'Camembert']
print(cheeses)
del cheeses[1]
print(cheeses)Exercise 21-14
Because intervals are “ends exclusive,” we can compute the length of a slice as end - start:
%%sandbox
l = [7, 4, 6, 2, 8, 1]
start = 1
end = 4
print("{} has length {}".format(l[start:end], end-start))Consider what this code would look like if ends were included in intervals.
Exercise 21-15
Another advantage of “ends exclusive” intervals is that you only need one index to split a list in two:
%%sandbox
numbers = [1, 2, 3, 4, 5, 6]
i = 3
beginning = numbers[:i]
end = numbers[i:]
print(beginning + end)If ends were included in intervals, this would be more complex.
Exercise 21-16
Do all the substitution and reduction steps in your head (or on paper) before you read any of the following code. Think carefully and decide what you think will be printed below. Remember that the value of a list is a container that holds other values in it. Then, read the code and see if you are right. If you were not, figure out what led you to the wrong conclusion.
%%codelens
x = 'A'
y = 'B'
z = 'C'
lst = [x, y, z]
print(lst)
x = 'Preben'
print(lst) # what is printed here?
lst[0] = 'Mogens'
print(lst) # what is printed here?Exercise 21-17
What do you think print(a) shows here? Decide before you run the code.
%%codelens
a = [1, 2, 3]
b = a
b.append(4)
print(a)Why did a change here, even though you only called append on b?
Exercise 21-18
Do you remember this trick from string slicing?
%%sandbox
l = [1, 2, 3, 4, 5]
print(l[::-1])Exercise 21-19
You can produce a list by splitting a long string into smaller parts. Think: “Hey string, split yourself on this smaller string”. Try these variations to figure out how it works.
%%sandbox
print("Homo sapiens neanderthalensis".split(" "))
print("Homo sapiens neanderthalensis".split('en'))
print(list('ATGCTCGTAACGACACTGCACTACTACAATAG'))
print("1, 2, 3, 5, 3, 2, 5, 3".split(', '))
print("1,2,3,5,3,2,5,3".split(','))
print('ATGCTCGTAACGACACTGCACTACTACAATAG'.split())
print("Homo sapiens neanderthalensis".split())Notice that the method has a default behavior when no argument is passed to it.
Exercise 21-20
You can produce a string by joining the elements of a list (if all the elements are strings, of course). Think: “Hey string, put yourself between all the strings in this list”. Run the code below:
%%sandbox
print("-".join(['Homo', 'sapiens', 'neanderthalensis']))
print("...".join(['Homo', 'sapiens', 'neanderthalensis']))
print("".join(['A', 'T', 'G']))Notice how you can join something on an empty string. This is a very useful technique to turn a list of characters into a string.
Exercise 21-21
This is the new badge from Chapter 19, and it comes with a rule: you check the translation in both directions.
Take this line:
%%sandbox
print(len(['ATG', 'GCC', 'TAA'][1:]))First write down, in one English sentence and without running anything, what it does. Then give the line to the assistant and ask it for one English sentence. Put the two side by side. Do they agree? Is one of them vague exactly where the other is precise? Now open a fresh conversation, give it your sentence and nothing else, and ask for the Python that does what it says. Run what comes back, and run the original. If they disagree, one of the two translations was wrong, and working out which one is the whole exercise.
General exercises
What does this expression reduce to? 'aaaaa', 'BaBaBa', or 'Banan'. Make up your mind, and then run the expression to check.
%%sandbox
'a'.join('Banana'.split('a')[:3] * 4)[-5:]