CS 61A Lab 4

Lists and dictionaries

Starter Files

Lists

Previously, we had dealt with tuples, which are immutable sequences.
Python has built-in lists, which are mutable. This means you can modify
lists without creating entirely new ones. Lists have state, unlike
tuples.

Just like with tuples, you can use slicing notation with lists. In
addition, not only can retrieve a slice from a list, you can also
assign to a slice of a list. This is possible because lists are
mutable.

Question 1

What does Python print? Think about these before typing it into an
interpreter!

Prioritize solving these problems with iteration, but for extra
practice, also solve them using recursion. Remember: these functions
should NOT return anything. This is to emphasize that these functions
should utilize mutability.

List Comprehensions

So far, we've covered lists, a powerful, mutable data structure that
supports various operations including indexing and slicing. Similar
to the generator expressions you've seen previously, lists can be
created using a syntax called "list comprehension." Using a list
comprehension is very similar to using the map or filter functions,
but will return a list as opposed to a filter or map object.

Question 7

Now write a list comprehension that will create a deck of cards. Each
element in the list will be a card, which is represented by a tuple
containing the suit as a string and the value as an int.

def deck():
return ________________

Python also includes a powerful sort method. It can also take a
key function that tells sort how to actually sort the objects. For
more information, look at
Python's documentation for the sort method
Note that sort is a stable sort. Now, use the sort method to
sort a shuffled deck. It should put cards of the same suit together,
and also sort each card in each suit in increasing value.

def sort_deck(deck):
"*** YOUR CODE HERE ***"

Dictionaries and Shakespeare

First, let's talk about dictionaries. Dictionaries are simple an
unordered set of key-value pairs. To create a dictionary, use the
following syntax:

>>> webster = {'Shawn': 'pineapple', 'Kim': 'blueberry'}

The curly braces denote the key-value pairs in your dictionary. Each
key-value pair is separated by a coma, and for each pair the key
appears to the left of the colon and the value appears to the right of
the colon. You can retrieve values from your dictionary by 'indexing'
using the key:

>>> webster['Shawn']
'pineapple'
>>> webster['Kim']
'blueberry'

You can modify an entry for an existing key in the dictionary using
the following syntax. Adding a new key follows identical syntax!

Now that you know how dictionaries work, we can move on to our next
step -- approximating the entire works of Shakespeare! We're going to
use a bigram language model. Here's the idea: We start with some word
-- we'll use "The" as an example. Then we look through all of the
texts of Shakespeare and for every instance of "The" we record the
word that follows "The" and add it to a list, known as the
successors of "The". Now suppose we've done this for every word
Shakespeare has used, ever.

Let's go back to "The". Now, we randomly choose a word from this list,
say "cat". Then we look up the successors of "cat" and randomly choose
a word from that list, and we continue this process. This eventually
will terminate in a period (".") and we will have generated a
Shakespearean sentence!

The object that we'll be looking things up in is called a "successor
table", although really it's just a dictionary. The keys in this
dictionary are words, and the values are lists of successors to those
words.

Question 8

Here's an incomplete definition of the build_successors_table
function. The input is a list of words (corresponding to a
Shakespearean text), and the output is a successors table. (By
default, the first word is a successor to "."). See the example below:

Question 9

Let's generate some sentences! Suppose we're given a starting word. We
can look up this word in our table to find its list of successors, and
then randomly select a word from this list to be the next word in the
sentence. Then we just repeat until we reach some ending punctuation.

Hint: to randomly select from a list, first make sure you import the
Python random library with import random and then use the expression
random.choice(my_list))

This might not be a bad time to play around with adding strings
together as well. Let's fill in the construct_sent function!

Great! Now all that's left is to run our functions with some actual
code. The following snippet included in the skeleton code will return
a list containing the words in all of the works of Shakespeare.

>>> def sent():
return construct_sent('The', table)
>>> sent()
' The plebeians have done us must be news-cramm'd '
>>> sent()
' The ravish'd thee , with the mercy of beauty '
>>> sent()
' The bird of Tunis , or two white and plucker down with better ; that's God's sake '

Now, if we want to start the sentence with a random word, we can use
the folowing:

>>> def random_sent():
import random
return construct_sent(random.choice(table['.']), table)
>>> random_sent()
' You have our thoughts to blame his next to be praised and think ?'
>>> random_sent()
' Long live by thy name , then , Dost thou more angel , good Master Deep-vow , And tak'st more ado but following her , my sight Of speaking false !'
>>> random_sent()
' Yes , why blame him , as is as I shall find a case , That plays at the public weal or the ghost .'