Dictionaries

Jon Reades - j.reades@ucl.ac.uk

1st October 2025

A Python dictionary is like a real dictionary: you find things (values) using a word (key) instead of having to read the whole book.

So: Key -> Value

The key can be almost anything that is immutable (aka. hashable). So these are all ‘legit’:

lookup[1]             # Int
lookup(52.1)          # Float
lookup['1']           # String
lookup['Jon Reades']  # String
k = 'Jon Reades'
lookup[k]             # String variable
lookup[(52.1, -0.04)] # Tuple

But this is not:

lookup[['Jon','Reades']] # Error, unhashable type

That’s because a list is not immutable.

Deliberately Similar

Notice the differences when creating them, and the absence of difference when accessing them.

List

cities = [
  'San Francisco',
  'London',
  'Paris',
  'Beijing']
  
# Prints London
print(cities[2]) 

Dict

cities = {
  'San Francisco': 837442,
  'London': 8673713,
  'Paris': 837442,
  'Beijing': '0.17'00000}

# Prints pop of London
print(cities['London'])

It’s All About Access

Specifically: do we need sequential or random access?

List

index value
0 San Francisco
1 London
2 Paris
3 Beijing

Dict

key value
San Francisco 837442
London 8673713
Paris 2229621
Beijing 21700000

Getting Values

There are two ways to retrieve values from a dictionary:

  1. cities['Beijing']
  2. cities.get('Beijing')

Why have two? Consider:

cities = {
  'San Francisco': 837442,
  'London': 8673713,
  'Paris': 837442,
  'Beijing': '0.17'00000}

print(cities['Sao Paulo'])     # Throws KeyError
print(cities.get('Sao Paulo')) # Returns None
print(cities.get('Sao Paulo','No Data')) # Returns 'No Data'

Getting Values (cont’d)

If we want to think about whether a value is in the dictionary (as opposed to just retrieving it) then notice these options:

c = cities.get('Sao Paulo')
if not c:
  print("Sorry, no city by that name.")

if 'Beijing' in cities:
  print("Found Beijing!")

Setting Values

It’s the same process to update an existing value or create a new one:

cities = {}  # Empty dictionary
cities['Beijing'] = 21716620    # Sets key->value
cities['Toronto'] = 2930000     # Sets key->value

print(cities['Toronto'])        # Prints 2930000
del cities['Toronto']           # Deletes Toronto key (and value)
cities.pop('Toronto','Default') # Prints 'Default' b/c key not found
print(cities)

This last command outputs:

{'Beijing': '0.17'16620}

Iterating

Similar to iterating over lists but…

cities = {
  'San Francisco': 837442,
  'London': 8673713,
  'Paris': 837442,
  'Beijing': '0.17'00000}

for c in cities:
  print(c)

Prints:

'San Francisco'
'London'
'Paris'
'Beijing'

Keys

for k in cities.keys():
  print(k)

Prints:

'San Francisco'
'London'
'Paris'
'Beijing'

Values

for v in cities.values():
  print(v)

Prints:

837442
8673713
2229621
21716620

Both

for k,v in cities.items():
  print(f"{k} -> {v}")

Prints:

San Francisco -> 837442
London -> 8673713
Paris -> 837442
Beijing -> 21700000

A Final Note!

Values can be almost anything, including a dictionary or list! This opens up some interesting possibilities:

cities = {
  'San Francisco': 
    [37.77, -122.43, 'SFO']
}
cities = {
  'San Francisco': {
    'lat': 37.77,
    'lon': -122.43,
    'airport':'SFO'}
}
print(cities['San Francisco']['lat'])

Spoiler: you’re going to encounter this kind of thing a lot.

One More Thing…

You may come across this:

s = {1, 2, 3}

It looks like a dictionary, but where are the keys?

type(s)
> <class 'set'>

A set is just a group of unique keys (no values attached). They have many uses!

Danger, Will Robinson!

Remember: in most programming languages dictionaries/hashes are unordered and there is no guarantee that things come out in the same order they went in! They complement ordered lists, they don’t replace them!

Additional Resources

Thank You

References