Skip to content
VLSI Mentor

Python Part I · Module 8 · Dictionaries

Dictionaries or Lists: Which to Use

Both of these structures hold several things, both can grow, and both can be walked through. Asked which is better, there is no answer — asked how you intend to find the data again, there usually is one immediately. A list remembers the order things came in and lets you reach the third one. A dictionary forgets nothing about which name goes with which value and lets you ask for the one you want by that name. Almost every real decision between them is settled by that difference, and the chapters you have just finished supply the evidence: the operations each structure offers are not arbitrary feature lists but consequences of what it is organised around.

Foundation13 min readPythonPart IFundamentalsDictionariesDesign

Part I · Module 8 · Chapter 8.8 · Dictionaries or Lists: Which to Use

1. Two Shapes for Test Names

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

Both hold two test names, and they are not alternatives for the same job.

order is the sequence tests run in. smoke is first because it runs first, and that is the entire content — there is no "value" attached to a test name here, only its place in the queue.

status is one outcome per test. There is no first test and no queue; there is a name and what happened to it.

2. The One Question

A decision figure. At the top, one question node asking how you will look the data up again. Two arrows lead down from it. The arrow labelled position leads down-left to a node for list, whose example is an ordered sequence of two test names. The arrow labelled name leads down-right to a node for dict, whose example maps each test name to its status.how will you look itup again?by where it sits, or by aname you know?listorder = ["smoke", "reset"]dictstatus = {"smoke": "PASS"}positionname12
Figure 1 — the decision. Ask how you intend to find the data again. If you will reach it by its place in a sequence, or if the order itself carries meaning, you need a list. If you will ask for it by a name you already have in your hand, you need a dictionary. Nothing about capability or speed enters this question.

How will you look this up again?

If the answer involves where it is — the first one, the next one, the order they came in — that is a list.

If the answer involves what it is called — the status of reset, the width of clk — that is a dictionary.

3. What Each One Can Answer

The capabilities follow from the organising principle rather than being arbitrary.

A list has positions, so it can answer questions about place:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
order = ["smoke", "reset"]
print(order[0])
print(order[-1])
print(order.index("reset"))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
smoke
reset
1

The first, the last, and where a given name sits. A dictionary can answer none of those — Chapter 8.1 showed d[0] is KeyError: 0, because 0 is read as a key.

A dictionary has keys, so it can answer questions about association:

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

A list cannot do that at all without searching.

The membership comparison

Both support in, and this is where the difference is sharpest:

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

Four lines, one operator, four different questions:

  • "smoke" in order — is this an element of the list?
  • "smoke" in status — is this a key?
  • "PASS" in status — is this a key? No — and "PASS" is a value, so the answer is False.
  • "PASS" in status.values() — is this a value? Yes.

The third line is Chapter 8.3's rule arriving where it does the most damage: a reader comparing the two structures assumes in means the same thing on both, and it does not.

Duplicates

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
l = ["smoke", "reset", "smoke"]
d = {"smoke": "PASS", "reset": "FAIL", "smoke": "SKIP"}
print(len(l), len(d))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
3 2

The list kept all three; the dictionary has two entries, because the repeated key replaced the first value — Chapter 8.2's rule.

That is a design consideration, not a quirk. If a test can appear twice and both appearances matter, a dictionary keyed by test name will silently lose one.

4. The Same Data, Both Ways

Pairs of names and outcomes can be held either way:

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

Same answer, two routes. pairs[1][1] says the second pair, its second field — and you had to know that reset is second. table["reset"] says what it means.

And they convert in both directions:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
pairs = [("smoke", "PASS"), ("reset", "FAIL")]
table = {"smoke": "PASS", "reset": "FAIL"}
print(dict(pairs))
print(list(table.items()))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
{'smoke': 'PASS', 'reset': 'FAIL'}
[('smoke', 'PASS'), ('reset', 'FAIL')]

Chapter 8.6's dict(pairs) and Chapter 8.5's .items(), which is why the list-of-tuples shape from Chapter 6.7 keeps appearing — it is the sequence form of the same information.

5. Records: a List of Them, or a Dictionary of Them

For nested data the same question applies one level up:

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

The list version keeps the records in order and repeats the test name inside each one. The dictionary version uses the test name as the key and does not store it twice.

Choose by the same question: if you will process them in order, the list is right; if you will ask about a named test, the dictionary is. Chapter 8.7 covers reading either.

6. Reasons That Are Not the Reason

Two arguments come up and neither should decide the choice.

"Dictionaries are faster." There is a real difference in one specific place: finding something by name. A dictionary goes more or less straight to it, for the reason Chapter 7.2 gave about hashing; a list has to look through its elements. For ten items that is irrelevant. For ten thousand items looked up repeatedly it is the difference between a script that finishes and one that does not.

But notice what that actually says. It is not "dictionaries are faster" — it is "looking something up by name is what a dictionary is for", which is the same sentence as Section 2. The speed is a consequence of using the right structure, not an independent reason to pick one.

"Dictionaries are more modern / more Pythonic." Not a reason. A queue of jobs is a list in any language and any era.

7. Side by Side

Now that each point has been demonstrated:

listdict
Found bypositionkey
Orderkept, and meaningfulinsertion order kept, not used for lookup
Repeatskept as separate itemsa repeated key replaces
x[0]the first elementKeyError: 0
x["name"]TypeErrorthe mapped value
v in xis it an element?is it a key?
.index(v)yesno
len() countsitemsentries

Both are mutable, and both preserve the order things were added — so neither mutability nor order is what separates them. Lookup is.

8. Predict, Run, Observe

Predict every line before reading on.

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

The verified output:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
2 2
smoke
PASS
True
True
False
True
1

Same length, and then every line after that is doing something different.

"reset" in suite and "reset" in status are both True for different reasons — an element in one case, a key in the other.

"FAIL" in status is False. It is a value, and in on a dictionary asks about keys only. The next line, against .values(), is True.

And suite.index("reset") is 1; status has no .index at all, because asking where a key sits is not a question a mapping answers.

9. Exercises

Exercise 1 — apply the question. For each, choose list or dictionary and give the one-sentence reason: (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 (e) the runtimes in the order they were measured (f) which simulator each project uses

Exercise 2 — predict. For l = ["a", "b"] and d = {"a": 1, "b": 2}, give each result; two raise: (a) l[0] (b) d["a"] (c) d[0] (d) "a" in l (e) "a" in d (f) 1 in d (g) 1 in d.values() (h) l.index("b") (i) d.index("b")

Exercise 3 — the membership trap. Explain in three sentences why "PASS" in status is False when "PASS" is clearly in the dictionary, and give the expression that asks the question the author meant.

Exercise 4 — both ways. Express "smoke passed, reset failed" as a list of pairs and as a dictionary. Write the expression that gets reset's outcome from each, and say in one sentence which you would rather read in six months.

Exercise 5 — convert. Given pairs = [("a", 1), ("b", 2)], write the line producing the dictionary form. Given that dictionary, write the line producing the list of pairs back. Name the chapter that taught each.

Exercise 6 — when a list is still right. Give two situations where results should stay a list of pairs rather than becoming a dictionary, and explain each in one sentence.

Exercise 7 — the duplicate. A script does table[test] = status for 200 records and ends with len(table) == 173. Say what the list form would have given instead, and in one sentence which is correct — being careful not to assume.

Exercise 8 — reject the reason. A colleague converts an ordered job queue into a dictionary "because dictionary lookup is faster". Write three sentences: what breaks, why the speed claim is irrelevant here, and what question they should have asked.

10. Summary

  • Ask how you will look the data up again. By position or order means a list; by a name you already hold means a dictionary.
  • A list is indexed by position; a dictionary is indexed by meaning.
  • A list answers x[0], x[-1] and .index(v). A dictionary answers none of them — d[0] is KeyError: 0.
  • A dictionary answers d["name"]. A list cannot without searching.
  • in asks a different question on each: an element of the list, or a key of the dictionary. "PASS" in status is False; "PASS" in status.values() is True.
  • A list keeps repeats; a repeated dictionary key replaces. That silently loses data if a name can legitimately occur twice.
  • The same information converts both ways — dict(pairs) and list(d.items()).
  • For records, ask the question one level up: a list of records keeps order, a dictionary of records is keyed by name.
  • Speed is a consequence, not a reason. Looking something up by name is what a dictionary is for; if you are searching a list for names repeatedly, that is the signal.
  • Both are mutable and both preserve insertion order — neither of those separates them. Lookup does.

One chapter remains, and it widens this question to every structure in Part I.

Where this fits

Part of the Python curriculum.