So far we've seen four operations relating to dictionary values:
{}
Creates an empty dictionary d[k]
Retrieves/sets the value associated with key k
k in d
Tests whether key k
exists in dictionaryd
d.keys()
Returns a sequence of all keys in dictionary d
Now we'll examine a few more operations that are also useful.
To create a dictionary with some key-value pairs built in upon creation, you can simply identify the key-value pairs separated by commas within the braces, with the key and value in each pair separated by colons:
pres = { 'Clinton': 1992, 'Bush': 2000, 'Obama': 2008 }
While you can use k in d
to test whether a key is
present in the dictionary, you can test whether a key
is absent using k not in d
.
if letter not in counts: # Associate 0 with 'letter' if 'letter'
counts[letter] = 0 # is not in 'counts' yet.
To iterate through every key in the dictionary, you can
use “for k in d
”. Note, though, that the order in
which we iterate is not predictable.
total = 0
for key in counts:
total += counts[key]
print('Total of all values is ' + str(total))
The len
function returns the number of keys in
the dictionary, as in “num_distinct = len(counts)
”.
The get
method takes two parameters, a key and a
“default value.” If the key is present in the
dictionary, then the result is the value associated with that
key; but if the key is absent, the result is the “default
value.”
letter_count = counts.get(letter, 0)
The pop
method takes a key as a parameter and
deletes the key and its associated value from the dictionary.
“counts.pop('e')”.
As an example using this, suppose we have a dictionary
words
mapping strings to values, and we want to delete
all keys that less than four characters long.
for w in words:
if len(w) < 4:
words.pop(w) # does not work!
Unfortunately, this won't work: Python forbids you to modify
the dictionary even as you're stepping through it. (This isn't
specific to pop
: Adding a new key during iteration is
also forbidden.)
So how can you do this? You would create a separate list, and as you find keys to pop you would add it into the list rather than actually pop them. Only after you've completed the iteration would you then iterate through the list, popping out the keys found in the list.
First, recall that earlier we developed a program counting how many letters occur in a word typed by the user. The approach we saw before is listed at left below; the listing at right gives an alternative approach.
word = input()
counts = {}
for letter in word:
if letter in counts:
counts[letter] += 1
else:
counts[letter] = 1
for letter in sorted(counts.keys()):
print('{0} {1:2d}'.format(letter, counts[letter]))word = input()
counts = {}
for letter in word:
old_count = counts.get(letter, 0)
counts[letter] = old_count + 1
for letter in counts: # Changed: unpredictable order!
print('{0} {1:2d}'.format(letter, counts[letter]))
The if
statement before is now replaced with the
get
method — something that cleans up the
implementation considerably. The other change is in the
for
statement: It is also much shorter, but there is a
key difference: Whereas the initial program would display the
letters in alphabetical order, the second program displays the
letters in an unpredictable order. If you wanted alphabetical
order, you would want to use the initial version.
Or here's another example: Suppose we have a list sents
of
sentences, and we want to create an “index” mapping
each word to the sentence containing that word.
index = {}
for s in sents: # (iterate through each sentence,
for w in s.split(): # and through each word in each sentence.)
index[w] = s # WARNING: a problem explained below
Note, though, that with each word is associated a sentence in which the word is found. But what if the word appears in multiple sentences? In this snippet, when we found the word in the second sentence, we'd overwrite the previous word/sentence pair with the new word/sentence pair, forgetting that there was another sentence.
To get around this, we'll change our dictionary to map words to lists of sentences containing the word.
index = {}
for s in sents: # (iterate through each sentence,
for w in s.split(): # and through each word in each sentence.)
if w in index:
index[w].append(s) # already seen, append to list
else:
index[w] = [s] # not seen before, create list with just s