Chapter 10

Lists

A sequence of elements of any type.


In [11]:
L = [1,2,3]
M = ['a', 'b', 'c']
N = [1, 'a', 2, [32, 64]]

Lists are mutable while strings are immutable. We can never change a string, only reassign it to something else.


In [12]:
S = 'abc'
#S[1] = 'z' # <== Doesn't work!
L = ['a', 'b', 'c']
L[1] = 'z'
print L


['a', 'z', 'c']

Some common list procedures:

reduce

Convert a sequence (eg list) into a single element. Examples: sum, mean

map

Apply some function to each element of a sequence. Examples: making every element in a list positive, capitalizing all elements of a list

filter

Selecting some elements of a sequence according to some condition. Examples: selecting only positive numbers from a list, selecting only elements of a list of strings that have length greater than 10.

Everything in Python is an object. Think of an object as the underlying data. Objects have individuality. For example,


In [28]:
a = 23
b = 23
a is b


Out[28]:
True

In [21]:
list1 = [1,2,3]
list2 = [1,2,3]
list1 is list2


Out[21]:
False

list1 and list2 are equivalent (same values) but not identical (same object). In order to make these two lists identical we can alias the object.


In [23]:
list2 = list1
list1 is list2


Out[23]:
True

Now both names/variables point at the same object (reference the same object).


In [25]:
list1[0] = 1234
print list1
print list2


[1234, 2, 3]
[1234, 2, 3]

In [ ]:
Back to the strings,

In [1]:
b = 'abc'
a = b
a is b


Out[1]:
True

Let's try to change b by assigning to a (they reference the same object after all)


In [31]:
a = 'xyz'
print a
print b


xyz
abc

What happened is that we have reassigned a to a new object, that is they no longer point at the same object.


In [32]:
a is b


Out[32]:
False

In [ ]:
id(b)

All exercises from Downey, Allen. Think Python. Green Tea Press, 2014. http://www.greenteapress.com/thinkpython/

Exercise 10.1 (Dan)

Write a function called nested_sum that takes a nested list of integers and add up the elements from all of the nested lists.

Exercise 10.2

Use capitalize_all to write a function named capitalize_nested that takes a nested list of strings and returns a new nested list with all strings capitalized.

def capitalize_all(t):
    res = []
    for s in t:
        res.append(s.capitalize())
    return res

Exercise 10.3

Write a function that takes a list of numbers and returns the cumulative sum; that is, a new list where the ith element is the sum of the first i+1 elements from the original list. For example, the cumulative sum of [1, 2, 3] is [1, 3, 6].

Exercise 10.4 (Wendy)

Write a function called middle that takes a list and returns a new list that contains all but the first and last elements. So middle([1,2,3,4]) should return [2,3].

Exercise 10.5 (Wendy)

Write a function called chop that takes a list, modifies it by removing the first and last elements, and returns None.

Exercise 10.6 (Sarah)

Write a function called is_sorted that takes a list as a parameter and returns True if the list is sorted in ascending order and False otherwise. You can assume (as a precondition) that the elements of the list can be compared with the relational operators <, >, etc. For example, is_sorted([1,2,2]) should return True and is_sorted(['b','a']) should return False.

Exercise 10.7 (Sarah)

Two words are anagrams if you can rearrange the letters from one to spell the other. Write a function called is_anagram that takes two strings and returns True if they are anagrams.

Exercise 10.8

The (so-called) Birthday Paradox:

  • Write a function called has_duplicates that takes a list and returns True if there is any element that appears more than once. It should not modify the original list.
  • If there are 23 students in your class, what are the chances that two of you have the same birthday? You can estimate this probability by generating random samples of 23 birthdays and checking for matches. Hint: you can generate random birthdays with the randint function in the random module.

Exercise 10.9 (Masa)

Write a function called remove_duplicates that takes a list and returns a new list with only the unique elements from the original. Hint: they don’t have to be in the same order.

Exercise 10.10

Write a function that reads the file words.txt and builds a list with one element per word. Write two versions of this function, one using the append method and the other using the idiom t = t + [x]. Which one takes longer to run? Why? Hint: use the time module to measure elapsed time.

Exercise 10.11 (Liu)

To check whether a word is in the word list, you could use the in operator, but it would be slow because it searches through the words in order. Because the words are in alphabetical order, we can speed things up with a bisection search (also known as binary search), which is similar to what you do when you look a word up in the dictionary. You start in the middle and check to see whether the word you are looking for comes before the word in the middle of the list. If so, then you search the first half of the list the same way. Otherwise you search the second half.

Either way, you cut the remaining search space in half. If the word list has 113,809 words, it will take about 17 steps to find the word or conclude that it’s not there.

Write a function called bisect that takes a sorted list and a target value and returns the index of the value in the list, if it’s there, or None if it’s not.

Exercise 10.12

Two words are a “reverse pair” if each is the reverse of the other. Write a program that finds all the reverse pairs in the word list.

Exercise 10.13

Two words “interlock” if taking alternating letters from each forms a new word. For example, “shoe” and “cold” interlock to form “schooled.”

  1. Write a program that finds all pairs of words that interlock. Hint: don’t enumerate all pairs!
  2. Can you find any words that are three-way interlocked; that is, every third letter forms a word, starting from the first, second or third? Credit: This exercise is inspired by an example at http://puzzlers.org.