, ,

Store Data by Name with Python Dictionaries (Python for Beginners, Part 8)

Dictionaries store data as key and value pairs so each number keeps its label. Read keys safely with .get(), update entries, loop over pairs, and total spend by category.

Python for Beginners · Part 8 of 20

A list is happy to hold 12000, 150 and 40. It just cannot tell you that 12000 was the rent and 150 was coffee. As soon as each number needs a name attached, a plain list starts to fight you. A dictionary is built for exactly this. It stores pairs, a key you look something up by and a value you get back, so a number stops being anonymous.

If Part 7 on lists, tuples and sets is behind you, you are ready. You need Python 3 and a text editor, nothing to install. Give this about fifteen minutes. Every block below is copy and run, and the output shown underneath is what you should see on your own screen. Terms get explained before they are used, because this series is for someone early in a coding career, not for someone who already knows the jargon.

Start hereA dictionary maps a key to a value. You write it with curly braces and colons, like {‘rent’: 12000}. Ask for prices[‘rent’] and Python hands back 12000. Keys are usually short strings, values can be almost anything. If you remember one thing today, remember that a dictionary is for looking data up by name.

What a dictionary holds

Think of the contacts on your phone. You do not scroll to position 47 to find a friend. You look them up by name and get their number back. A dictionary works the same way. The name is the key, the number is the value, and the lookup goes straight to the answer instead of walking through everything.

prices key value ‘rent’ 12000 ‘coffee’ 150 ‘bus’ 40

A dictionary looks up a value by its key.

Making one and reading it back

prices.py
prices = {'rent': 12000, 'coffee': 150}
print(prices['rent'])
print(len(prices))
output
12000
2

The curly braces make the dictionary. Each pair is written as key: value, and pairs are separated by commas. Square brackets do the lookup, so prices[‘rent’] means give me the value stored under ‘rent’. The len function counts how many pairs there are.

Run it with python prices.py on Windows, or python3 prices.py on macOS and Linux. One trap when you copy code off a web page: the straight quotes around ‘rent’ can arrive as curly quotes, and Python stops with a SyntaxError. If that happens, delete them and type the quotes yourself.

Reading a key that might not be there

The most common early stumble with dictionaries is asking for a key that does not exist. Watch what happens.

missing.py
prices = {'rent': 12000, 'coffee': 150}
print(prices['metro'])
output
Traceback (most recent call last):
  File "missing.py", line 2, in <module>
    print(prices['metro'])
          ~~~~~~^^^^^^^^^
KeyError: 'metro'

Read the last line first. KeyError: ‘metro’ means the key metro is simply not in the dictionary. The last line of a traceback almost always names the real problem, so read it before anything above it. This is not a crash to fear. It is Python telling you plainly what it could not find.

When a key might be missing, use .get instead of square brackets. It returns None for a missing key, or a default you choose.

getvalue.py
prices = {'rent': 12000, 'coffee': 150}
print(prices.get('metro'))
print(prices.get('metro', 0))
output
None
0
You writeKey existsKey is missing
prices[‘metro’]gives the valueraises KeyError, stops
prices.get(‘metro’)gives the valuegives None, keeps going
prices.get(‘metro’, 0)gives the valuegives 0, keeps going
Same missing key, two outcomes prices[‘metro’] KeyError the program stops prices.get(‘metro’, 0) returns 0 the program continues

Square brackets stop on a missing key; .get keeps going.

Here is an opinion that goes against a lot of beginner tutorials. Many of them tell you to guard every lookup with if key in prices. That works, but it does two lookups where one would do, and it clutters simple code. Reach for .get(key, default) instead, and save in for the times you genuinely branch on whether something is present.

Adding, changing and removing entries

A dictionary can change after you make it. Assigning to a key adds it if it is new, or overwrites it if it already exists. The del keyword removes a pair.

edit.py
prices = {'rent': 12000, 'coffee': 150}
prices['coffee'] = 180
prices['bus'] = 40
print('bus' in prices)
del prices['rent']
print(prices)
output
True
{'coffee': 180, 'bus': 40}

Assigning to ‘coffee’ replaced 150 with 180, because a key can appear only once. Assigning to ‘bus’ added a brand new pair. The in check answers a plain yes or no, and del took the rent pair out for good.

Gotcha: a key has to stay stillA key must be something Python can freeze and rely on never changing, so strings, numbers and tuples are fine, but a list is not.
badkey.py
seen = {}
seen[['a', 'b']] = 1
output
Traceback (most recent call last):
  File "badkey.py", line 2, in <module>
    seen[['a', 'b']] = 1
    ~~~~^^^^^^^^^^^^
TypeError: unhashable type: 'list'
The words unhashable type: ‘list’ are Python saying a list can change, so it cannot be trusted as a key. Use a string or a tuple instead.

Walking through every pair

To visit each entry, loop over .items(). It hands you the key and the value together on every turn of the loop.

walk.py
prices = {'rent': 12000, 'coffee': 150}
for name, cost in prices.items():
    print(name, 'costs', cost)
output
rent costs 12000
coffee costs 150

The two names name and cost pick up the key and value on each pass. If you want only the keys, loop over the dictionary itself or over .keys(). For only the values, use .values().

views.py
prices = {'rent': 12000, 'coffee': 150}
print(list(prices.keys()))
print(list(prices.values()))
output
['rent', 'coffee']
[12000, 150]
TaskCodeWhat you get
Make a dictionaryd = {‘a’: 1}one pair, a maps to 1
Read a keyd[‘a’]the value, or KeyError
Read safelyd.get(‘a’, 0)the value, or 0
Add or changed[‘b’] = 2adds b, or overwrites it
Remove a keydel d[‘a’]the pair is gone
Is a key present‘a’ in dTrue or False
Count pairslen(d)how many pairs
Loop over pairsfor k, v in d.items()key and value each turn

Storing many values under one key

A key can hold only one value at a time, but that value can be a list. That is how you keep several things grouped under the same label. The pattern is the same get with a default you saw earlier, except the default is an empty list.

grouping.py
rows = [
    ('food', 250),
    ('travel', 40),
    ('food', 120),
]
by_cat = {}
for category, amount in rows:
    items = by_cat.get(category, [])
    items.append(amount)
    by_cat[category] = items
print(by_cat)
output
{'food': [250, 120], 'travel': [40]}

For a new category, .get returns a fresh empty list, the amount is appended, and the list goes back under that key. For a category you have seen before, .get returns the list already there and the new amount joins it. You end with every amount grouped by its category, ready to total or count. This one dictionary of lists is enough to power a simple report, and it uses nothing beyond what you already know.

A worked example: totalling spend by category

Here is a real job a dictionary does well. You have a stack of expenses, each with a category and an amount, and you want the total spent per category. The trick is .get(category, 0): it starts a new category at zero, then adds to it every time that category shows up again.

bycategory.py
rows = [
    ('food', 250),
    ('travel', 40),
    ('food', 120),
    ('fun', 220),
    ('travel', 60),
]
totals = {}
for category, amount in rows:
    old = totals.get(category, 0)
    totals[category] = old + amount
print(totals)
output
{'food': 370, 'travel': 100, 'fun': 220}

The first time food appears, .get returns 0, so the total becomes 250. The second time, it returns 250 and the total climbs to 370. No category needs to be set up in advance, and nothing raises KeyError. That small pattern, get with a default then write back, is one you will reuse for the rest of your Python life.

Spend by category 370 food 100 travel 220 fun

Grouping amounts by category with .get and a running total.

Project check-in: entries become recordsPart 7 stored a flat list of amounts, so the tracker knew every number but had lost the label again. Now each expense becomes a small dictionary with its own category, amount and note, and those dictionaries live inside a list.
expenses.py
print('My Expense Tracker')
expenses = []
while True:
    category = input('Category or done: ')
    if category == 'done':
        break
    amount = float(input('Amount: '))
    note = input('Note: ')
    expenses.append({
        'category': category,
        'amount': amount,
        'note': note,
    })
    print('Saved', category)
print('Entries:', len(expenses))
for e in expenses:
    print(e['category'], e['amount'], e['note'])
terminal
My Expense Tracker
Category or done: Food
Amount: 250
Note: lunch
Saved Food
Category or done: Bus
Amount: 40
Note: to office
Saved Bus
Category or done: done
Entries: 2
Food 250.0 lunch
Bus 40.0 to office
Each entry is a labelled record now, not a bare number. That one change is what lets later parts total by month, sort by category and save clean rows to a file.
Real interview question"What can you use as a dictionary key, and why not a list?" Keys must be hashable, which in practice means immutable: strings, numbers and tuples of those. A list can change after you use it, so Python refuses it with unhashable type: ‘list’. A good follow up is the difference between prices[‘x’] and prices.get(‘x’): the first raises KeyError when x is missing, the second returns None or a default you pick.
Try it yourselfCount how many times each colour appears in this sentence and print the counts as a dictionary.
task.py
sentence = 'red blue red green blue red'
# your code here
expected output
{'red': 3, 'blue': 2, 'green': 1}
Show solution
solution.py
sentence = 'red blue red green blue red'
counts = {}
for word in sentence.split():
    counts[word] = counts.get(word, 0) + 1
print(counts)
Why this matters in your first jobDictionaries turn up everywhere in real work. A config file loads into one. A reply from a web API arrives as dictionaries inside dictionaries. Rows from a database come back keyed by column name. When you group orders by customer or count errors by type, a dictionary is the tool you reach for. Getting comfortable now means the day one tasks feel familiar instead of strange.

Dictionary questions that come up

Are dictionaries kept in order?
Yes. Since Python 3.7 a dictionary keeps its pairs in the order you inserted them, so a loop over it is predictable.

Can two keys be the same?
No. A later assignment to the same key overwrites the earlier value. If you need many values under one key, store a list as the value.

How do I loop over only the keys?
Loop over the dictionary directly, or over .keys(). For only the values, use .values(). For both together, use .items().

Can a value be another dictionary?
Yes. Nesting is common, and it is exactly how JSON from an API looks. You will meet that properly in Part 16.

When should I not use a dictionary?
When order and position are the point, or when you just have a plain sequence of items with no names, a list is the simpler fit. Reach for a dictionary when the data has labels.

You can now store data as key and value pairs, read it safely with .get, add, change and delete entries, loop over every pair, and total values by category. That covers most of what day to day Python code does with dictionaries.

Part 9 turns the blocks of code you keep rewriting into named functions you call in one line, and the expense tracker finally gets an add_expense you can reuse. If you practise one thing before then, rebuild the colour counter from memory. The full series map lives on the Complete Guide.

Python for Beginners · Part 8 of 20
« Previous: Part 7  |  Complete Guide  |  Next: Part 9

About The Author


Discover more from Journal of Intelligent Infrastructure – By Dr Pranay Jha

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Architect’s Toolkit

About the Author

Dr. Pranay Jha is a Cloud and AI Consultant with 18+ years of experience in hybrid cloud, virtualization, and enterprise infrastructure transformation. He specializes in VMware technologies, multi-cloud strategy, and Generative AI solutions. He holds a PhD in Computer Applications with research focused on Cloud and AI, has published multiple research papers, and has been a VMware vExpert since 2016 and a VMUG Community Leader.

Discover more from Journal of Intelligent Infrastructure - By Dr Pranay Jha

Subscribe now to keep reading and get access to the full archive.

Continue reading