Skip to content
VLSI Mentor

Python Part I · Module 8 · Dictionaries

Key and Value: The Dictionary Mental Model

You now have four collections, and every one of them finds things the same way: by position, or by membership. A list element lives at a number. A tuple field lives at a number. A set answers only whether something is present. None of them lets you say what you actually mean when the data is a result — which test, and what happened to it. A dictionary does. It stores a value under a key you choose, and you retrieve it by naming that key rather than by counting. The syntax borrows square brackets from indexing, which makes it look familiar and is the single biggest source of confusion about it. This chapter is about the difference underneath, because everything else in the module follows from getting it right.

Foundation14 min readPythonPart IFundamentalsDictionariesMental Model

Part I · Module 8 · Chapter 8.1 · Key and Value: The Dictionary Mental Model

1. One Result, Several Named Fields

Here is the result of a single test run:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
result = {"test": "axi_smoke", "seed": 4210, "status": "PASS"}
print(result["status"])
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
PASS

result["status"] is read as "the status of result". You did not count anything and you did not need to know what order the fields were written in — you named the field you wanted.

The other two fields work the same way:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
result = {"test": "axi_smoke", "seed": 4210, "status": "PASS"}
print(result["test"])
print(result["seed"])
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
axi_smoke
4210

Each name inside the braces is a key. Each thing it is paired with is a value. The whole collection is a dictionary, and its job is to answer one question: given this key, what value is associated with it?

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
result = {"test": "axi_smoke", "seed": 4210, "status": "PASS"}
print(type(result))
print(len(result))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
<class 'dict'>
3

Type dict, and len() counts entries — three key-value pairs, not six items.

2. Four Layers, Kept Separate

It is worth naming the pieces precisely now, because the distinctions matter enormously by Chapter 8.6.

  • result is a name. Chapter 2.3 established what that means: a name refers to a value.
  • The thing it refers to is a dictionary.
  • Inside that dictionary, "status" is a key.
  • "PASS" is the value that key is mapped to.
Three nodes. On the upper row, a node for the name, holding result, with an arrow labelled refers to pointing right at a node for the dictionary, which holds three key-value entries. From the dictionary a second arrow points downward, labelled status, to a node for the value, which holds the string PASS.the nameresultthe dictionarythree key-value entriesthe value"PASS"refers tostatus12
Figure 1 — the four layers. The name refers to a dictionary; a key selects one value from inside it. These are separate things: changing what the name refers to is a different operation from changing what a key maps to, and Chapter 8.6 depends on keeping them apart.

Read the second arrow carefully: the key is what selects the value. A different key would arrive at a different value in the same dictionary.

3. A Key Is Not a Position

The square brackets are the same ones you used on strings, lists and tuples. What goes inside them is not.

A list selects by position:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
tests = ["PASS", "FAIL"]
print(tests[1])
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
FAIL

A dictionary selects by key:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
status = {"smoke": "PASS", "reset": "FAIL"}
print(status["reset"])
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
FAIL

Both printed FAIL, and the two lines mean completely different things. tests[1] says the element in position one. status["reset"] says the value filed under "reset".

4. The Experiment That Settles It

Reorder both collections and ask the same questions again.

The list first:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
tests2 = ["FAIL", "PASS"]
print(tests2[1])
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
PASS

tests2[1] now gives PASS. The expression did not change; its meaning did, because position one now holds something else. If the first version was asking "did reset fail?", the second version is silently asking about a different test and answering confidently.

Now the dictionary:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
status2 = {"reset": "FAIL", "smoke": "PASS"}
print(status2["reset"])
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
FAIL

Still FAIL. The key names the thing you meant, so rearranging the entries cannot change what the lookup finds.

And the two dictionaries really are the same value, despite being written differently:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
status = {"smoke": "PASS", "reset": "FAIL"}
status2 = {"reset": "FAIL", "smoke": "PASS"}
print(status == status2)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True

Equality compares the mapping — which keys map to which values — and not the order they were typed in. Chapter 8.2 returns to this.

5. The Lookup Produces an Ordinary Value

Nothing exotic comes back. You get the value itself, with its own type:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
rec = {"name": "axi_smoke", "seed": 4210, "passed": True}
print(type(rec["name"]), type(rec["seed"]), type(rec["passed"]))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
<class 'str'> <class 'int'> <class 'bool'>

A string, an integer and a boolean — whatever was stored. Which means a lookup is an expression like any other from Module 3, usable immediately:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
rec = {"name": "axi_smoke", "seed": 4210, "passed": True}
print(rec["seed"] + 1)
print(rec["name"].upper())
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
4211
AXI_SMOKE

Arithmetic on the integer, a string method on the string. No conversion, no unwrapping.

6. What d[0] Actually Does

Here is the most convincing demonstration in the chapter that the brackets mean something new.

Ask a dictionary for position 0:

Azvya Education Pvt. Ltd.VLSI Mentor
BROKEN ON PURPOSE
r = {"a": 1, "b": 2}
print(r[0])
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
KeyError: 0

Read that error. It is not a TypeError saying numbers are unacceptable, and it is not a complaint about subscripting. It is KeyError: 0 — Python took 0 as a key, went looking for it, and did not find one.

If the dictionary happened to have a key 0, that line would have worked and returned its value. The number was never interpreted as a position at all.

Slicing is the same story:

Azvya Education Pvt. Ltd.VLSI Mentor
BROKEN ON PURPOSE
r = {"a": 1, "b": 2}
print(r[0:1])
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
KeyError: slice(0, 1, None)

Python built a slice object, used that as the key, and failed to find it. There is no slicing concept here to reject — only keys that are present or absent.

7. What the Key Can Be

Keys are not restricted to strings. Anything that can serve as a stable label works:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
widths = {"clk": 1, "addr": 32, "data": 64}
print(widths["addr"])
print(type(widths["addr"]))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
32
<class 'int'>

Here the keys are signal names and the values are bit widths — which reads exactly as the data means. Chapter 8.2 covers what is and is not allowed as a key, building on Chapter 7.1's hashability rule.

8. Insertion Order Is Preserved

One factual point, stated carefully because Chapter 7.1 said something different about sets.

A modern Python dictionary remembers the order entries were added, and displays and iterates them in that order:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
d = {}
d["b"] = 2
d["a"] = 1
print(d)
print(list(d))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
{'b': 2, 'a': 1}
['b', 'a']

b was added first, so it comes first — not a, which would be alphabetical. That behaviour is defined and dependable, and it is genuinely different from a set, where Chapter 7.2 measured five different orders across twelve runs.

Insertion order is also not sorted order. Chapter 8.5 covers iteration properly.

9. Predict, Run, Observe

Predict all six before reading on. One raises.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
result = {"test": "axi_smoke", "seed": 4210, "status": "PASS"}
print(result["test"])
print(len(result))
print(result["seed"] + 10)
print(type(result["status"]))
print(result == {"status": "PASS", "seed": 4210, "test": "axi_smoke"})
print(result["runtime"])

The verified output for the first five:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
axi_smoke
3
4220
<class 'str'>
True

and the sixth:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
KeyError: 'runtime'

len() is 3 — three entries, not six values.

result["seed"] + 10 is 4220, because the lookup produced the integer itself.

The equality is True: same three keys mapped to the same three values, written in a different order. Order is not part of what a dictionary is for comparison purposes, even though it is remembered.

And the last line raises, because there is no "runtime" key. The error names the key it could not find — which is Chapter 8.3's whole subject.

10. Exercises

Exercise 1 — build a record. Create a dictionary describing one signal: its name, its bit width and whether it is an input. Print each field by naming its key, and print the number of entries.

Exercise 2 — key or position. For each expression, say whether it selects by position or by key, and what the brackets are asking for: (a) tests[0] where tests is a list (b) status["smoke"] (c) name[0] where name is a string (d) widths["clk"] (e) row[1] where row is a tuple

Exercise 3 — the reordering experiment. Given pairs = ["PASS", "FAIL"] and status = {"smoke": "PASS", "reset": "FAIL"}, write down what pairs[1] and status["reset"] produce. Now rewrite both with their two entries swapped and predict both again. Explain in two sentences which one changed meaning and why.

Exercise 4 — read the error. Run {"a": 1}[0] and write down the exact message. Explain in three sentences why it is a KeyError rather than a TypeError, and what that tells you about how Python read the brackets.

Exercise 5 — the value's type. For rec = {"seed": 4210, "name": "smoke", "ok": True}, predict the result and type of rec["seed"] * 2, rec["name"][:2] and rec["ok"]. Verify all three.

Exercise 6 — equality. Predict whether each is True, then verify: (a) {"a": 1, "b": 2} == {"b": 2, "a": 1} (b) {"a": 1} == {"a": 2} (c) {"a": 1} == {"a": 1, "b": 2}

Exercise 7 — insertion order. Write four lines that build an empty dictionary and add three entries in a deliberately non-alphabetical order, then print it. Say in one sentence what determined the printed order, and in one more why that still does not let you write d[0].

Exercise 8 — choose the shape. For each, say whether a list or a dictionary describes the data better, in one sentence each: (a) the order tests must run in (b) the status of each test (c) the lines of a log file (d) the bit width of each signal

11. Summary

  • A dictionary maps keys to values and answers one question: given this key, what value is associated with it?
  • result["status"] reads as "the status of result" — you name the field rather than counting to it.
  • Four separate layers: the name refers to a dictionary; a key selects a value. Keeping them apart matters from Chapter 8.6 onwards.
  • len() counts entries, not keys plus values.
  • A key is not a position. A list selects by arrangement; a dictionary selects by meaning.
  • Reordering breaks a position and not a key — the experiment in Section 4 is the whole argument for the structure.
  • The lookup produces the stored value, with its own type, usable immediately as an expression.
  • d[0] is KeyError: 0, not a TypeError. Python treated 0 as a key. d[0:1] uses the slice object as a key.
  • Dictionaries preserve insertion order and that is dependable — unlike a set. It still does not make lookup positional.
  • Equality compares the mapping, not the order entries were written in.

The next chapter builds dictionaries properly and settles what may be used as a key.

Where this fits

Part of the Python curriculum.