Skip to content
VLSI Mentor

Python Part I · Module 8 · Dictionaries

Choosing a Structure: String, List, Tuple, Dict or Set

Five modules have each ended by asking which of two structures fits. This chapter asks the question once, across all of them, because that is the decision that actually comes up — you have some data and nobody has told you what shape it is. Getting it right is worth more than remembering any method, for a reason worth stating plainly: a method you have forgotten costs you thirty seconds, and a structure chosen wrongly costs you every line of code that touches it, plus the bugs that arrive when the data changes. The good news is that three questions discriminate between all five, and you have already met every one of them.

Intermediate15 min readPythonPart IFundamentalsData StructuresDesign

Part I · Module 8 · Chapter 8.9 · Choosing a Structure: String, List, Tuple, Dict or Set

1. The Five, on One Page

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
one_name = "axi_smoke"
suite = ["smoke", "reset"]
job = ("axi_smoke", 4210)
record = {"test": "axi_smoke", "status": "PASS"}
failures = {"axi_burst", "reg_rw"}
print(type(one_name).__name__, type(suite).__name__, type(job).__name__,
      type(record).__name__, type(failures).__name__)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
str list tuple dict set

Five values, five types, all describing parts of the same regression. Each one is the right shape for a different question, and the rest of this chapter is about telling them apart before you write any code around them.

One detail worth noticing immediately:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
one_name = "axi_smoke"
suite = ["smoke", "reset"]
job = ("axi_smoke", 4210)
record = {"test": "axi_smoke", "status": "PASS"}
failures = {"axi_burst", "reg_rw"}
print(len(one_name), len(suite), len(job), len(record), len(failures))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
9 2 2 2 2

len(one_name) is 9, not 1. A string is a sequence of characters, so len() counts them. The other four are collections of two things each. A string is the odd one out and it is worth remembering when a name arrives where a collection was expected.

2. Three Questions

Five labelled blocks in two rows, joined by three arrows. Top row: string, holding one test name in quotes; list, holding an ordered suite of two names; and tuple, holding a fixed pair of a name and a seed. An arrow labelled split runs from string to list, and an arrow labelled fixed runs from list to tuple. Bottom row: dict, mapping a test key to a status value; and set, holding two unique failure names with no values. An arrow labelled no values runs from dict to set.one piece of text"axi_smoke"ordered, repeatsallowed["smoke", "reset"]fixed record("axi_smoke", 4210)key to value{"test": "axi_smoke"}unique, membershiponly{"axi_burst", "reg_rw"}splitfixedno values12
Figure 1 — the five structures and the literal form of each, with arrows marking the three relationships worth knowing. Splitting one piece of text gives an ordered collection. A list whose item count is fixed by what the data means is a tuple. A dictionary with no values left to store — only the keys themselves — is a set. Each arrow is a question Sections 3 to 7 answer.

Three questions get you to any of them.

Question 1 — is this one thing, or several?

A test name is one thing. "axi_smoke" is a string, and the fact that it is made of characters is incidental — you will not ask for its fourth letter. If it is one thing, you are done.

Question 2 — if it is several, do they have names, or positions?

Named means a dictionary: the status of reset, the width of clk. Chapter 8.8 settled this one.

Positional means a list or a tuple, and that needs Question 3.

Question 3 — is the number of items fixed by what the data means?

Fixed means a tuple: a (test, seed) pair is always two things, and a third element would make it something else. Chapter 6.7 settled this one.

Not fixed means a list: a suite gains tests, a log gains lines.

And the one question that bypasses the others: if the only thing you will ever ask is "is this value present?" — with order and repeats carrying no information — it is a set. Chapter 7.6 settled that.

3. String: One Piece of Text

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
name = "axi_smoke"
print(name.upper())
print(name[:3])
print(len(name))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
AXI_SMOKE
axi
9

A string is a sequence — of characters — so it indexes and slices. But you choose it because the data is one piece of text, not because you intend to work through its characters.

The mistake it prevents: treating a collection of names as one string joined together. If you find yourself splitting a string to get at items, the data was a list and something flattened it too early.

4. List: Ordered, Repeats Allowed

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
suite = ["smoke", "reset"]
suite.append("burst")
print(suite[0], suite[-1], len(suite))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
smoke burst 3

Position means something, repeats are real, and the collection grows.

The question it answers: what is first, what is next, what is the whole sequence?

The question it cannot: what is the status of reset? Only by searching.

5. Tuple: a Fixed Record

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
job = ("axi_smoke", 4210)
test, seed = job
print(test, seed)
print(len(job))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
axi_smoke 4210
2

Two positions whose meanings are fixed by what a job is. Chapter 6.5's unpacking is the natural way to read one.

The question it answers: what are the parts of this one thing?

The question it cannot: can I add another part? No — and that is the point, not a limitation.

Against a dictionary: a tuple's positions carry meaning only because you remember them. job[1] is the seed because you know it is. A dictionary says so. Prefer a tuple for small, universally understood pairs and when you need a key or a set member; prefer a dictionary when a reader would have to be told what position 2 means.

6. Dictionary: Key to Value

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
record = {"test": "axi_smoke", "status": "PASS"}
print(record["status"])
print(len(record))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
PASS
2

The question it answers: given this name, what is the associated value?

The question it cannot: what came first? There is an insertion order, but asking for "entry zero" is not something a mapping does — Chapter 8.1 showed d[0] is KeyError: 0.

7. Set: Membership Only

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
failures = {"axi_burst", "reg_rw"}
print("axi_burst" in failures)
print(len(failures))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
2

The question it answers: is this one of them? And, with Chapter 7.4's operations, what is in this group and not in that one?

The question it cannot: which failed first, or how many times. Both are discarded on the way in — Chapter 7.6 was about what that costs.

8. Real Data Is Usually a Combination

The question is rarely answered once. Most real structures apply it at two levels:

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

Three answers in one structure: a dictionary keyed by test name, each value a dictionary of named fields, and one of those fields a list of seeds because seeds are a sequence that grows.

Ask the three questions once per level and the shape falls out. Chapter 8.7 covers reading it.

Two combinations worth recognising because they appear constantly:

  • A list of tuples — [("smoke", "PASS"), ("reset", "FAIL")]. An ordered sequence of fixed records. Chapter 6.7 named this the most common shape in real data, and Chapter 8.5's .items() produces exactly it.
  • A dictionary of lists — {"axi_burst": [48211, 48215]}. Look up by name, then work through a sequence.

9. The Decision, Collected

By the question each structure answers — not by the methods each provides:

The question your data must answerStructureWritten
What is this one piece of text?str"axi_smoke"
What is the sequence, and what is first?list["smoke", "reset"]
What are the fixed parts of this one thing?tuple("axi_smoke", 4210)
Given this name, what is its value?dict{"test": "axi_smoke"}
Is this one of them?set{"axi_burst", "reg_rw"}

And the properties that discriminate, for when two seem to fit:

strlisttupledictset
Orderedyesyesyesinsertionno
Changeablenoyesnoyesyes
Repeats keptyesyesyesvalues onlyno
Found bypositionpositionpositionkeymembership
Can be a key or set memberyesnoif its parts cannono

That last row is worth a second look: it is Chapter 7.1's hashability rule, and it is the only property that decides what can go inside a set or be used as a dictionary key.

10. Predict, Run, Observe

For each description, name the structure before reading on, and say which question decided it.

  1. the lines of a log file, in order
  2. the name of the simulator being used
  3. a screen coordinate
  4. which tests failed at least once
  5. the runtime of each test
  6. the arguments to pass to a tool, built up as options are chosen
  7. one test's name, seed, status and runtime together

Then this, which is about the types:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
a = "clk"
b = ["clk"]
c = ("clk",)
d = {"clk": 1}
e = {"clk"}
print(len(a), len(b), len(c), len(d), len(e))
print(type(a).__name__, type(b).__name__, type(c).__name__, type(d).__name__, type(e).__name__)

The verified output:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
3 1 1 1 1
str list tuple dict set

The answers to the seven: list (order, grows), string (one piece of text), tuple (two fixed parts), set (membership, repeats meaningless), dictionary (by name), list (ordered, built up), dictionary (named fields of one thing).

And the code: len(a) is 3 — three characters — while every collection holding one item has length 1. The string is counting something different from the other four, which is Section 1's point in its smallest form.

11. Exercises

Exercise 1 — name the structure. For each, give the structure and the deciding question in one sentence: (a) the bit width of each signal (b) an RGB colour (c) every error code seen (d) the order of phases in a flow (e) a file path (f) one row of a results table with four named fields

Exercise 2 — predict. For x = "ab", y = ["ab"], z = ("ab",), w = {"ab": 1}, v = {"ab"}, give len() and type() for each, then explain the one that differs from the rest.

Exercise 3 — two levels. Design the structure for "for each project, which blocks it contains, and for each block its owner". Say which structure sits at each level and which question decided it.

Exercise 4 — the wrong choice. A script stores measured runtimes in a set so it can ask which values occurred. Explain in three sentences what goes wrong, which question was answered incorrectly, and what it should be.

Exercise 5 — tuple or dictionary. For a record of a test name and a seed, argue for the tuple in two sentences and for the dictionary in two sentences. Then say which you would choose if that record had to be a dictionary key, and why that settles it.

Exercise 6 — the combination. Identify the structures at every level of {"a": [("x", 1), ("y", 2)]} and say what question each level answers.

Exercise 7 — the hashability row. Explain in two sentences why a list cannot be a dictionary key or a set member while a tuple of strings can, and name the chapter that established the rule.

Exercise 8 — defend a change. A colleague wants to convert results = [("smoke", "PASS"), ("reset", "FAIL")] into a dictionary. Write three sentences: when that is clearly right, when it would lose information, and the one question you would ask before approving it.

12. Summary

  • Three questions decide it. Is this one thing or several? If several, are they found by name or by position? If by position, is the count fixed by what the data means?
  • One question bypasses the rest: if only membership matters, it is a set.
  • str — one piece of text. len() counts characters, which makes it the odd one out.
  • list — ordered, repeats kept, grows. Answers what is first, what is the sequence.
  • tuple — a fixed record whose positions have meaning. Answers what are the parts of this one thing.
  • dict — key to value. Answers given this name, what is its value.
  • set — distinct values, membership only. Answers is this one of them.
  • Only hashable values may be dictionary keys or set members — the single property that constrains what goes inside.
  • Real data is a combination. Ask the questions once per level; a list of tuples and a dictionary of lists are the two shapes you will meet most.
  • This decision outranks remembering methods. A forgotten method costs a search; a wrong structure costs every line that touches it.

That completes Module 8 — Dictionaries, and with it the collections half of Part I.

You began Module 4 able to work with one value at a time. You can now hold text and reach into it; hold an ordered collection that grows; hold a fixed record whose shape is part of its meaning; hold a group of distinct values and compare two such groups in one line; and hold a mapping from names you choose to values you store — building it, reading it safely when a field may be missing, changing it, walking it, copying it with full knowledge of what a copy does and does not protect, and nesting it when the data genuinely has levels.

The most valuable idea in this module is Chapter 8.1's, and it is worth carrying: a key is a fact about meaning, where a position is a fact about arrangement. Everything else followed from it — why d[0] is a KeyError rather than a TypeError, why reordering cannot break a lookup, why in checks keys, and why a dictionary is the structure most engineering results eventually live in.

What you still cannot do is decide. Every chapter in Part I so far has produced an answer — a boolean, a count, a status — without ever being able to act differently on it. "ERROR" in line has been available since Module 4 and you have never once been able to do one thing when it is true and another when it is false. Module 9 — Conditional Statements is that, and it is the point at which the values you have spent five modules learning to build finally start driving what a program does.

Where this fits

Part of the Python curriculum.