Concepts / Building Histograms from Data

Building Histograms from Data

The central decision is simple: if the character is new, create its dictionary entry with the count 1. If the character is already present, increase its existing count by 1.

  • Programming

Why Counts Need a Dictionary

Suppose you have the word brontosaurus and want to know how many times each letter appears. Counting by hand is possible, but a dictionary can keep one count for every unique character while a loop examines the word. Each character becomes a key, and its count becomes the value associated with that key.

Key point

The central decision is simple: if the character is new, create its dictionary entry with the count 1. If the character is already present, increase its existing count by 1.

bcount 1rcount 2ocount 2scount 2acount 1ucount 1
What does each character key contain as the histogram is built?

The First Counting Method

The conditional approach explicitly checks whether the current character is already a key in dictionary d. When c is not in d, the program assigns d[c] = 1 because this is the first occurrence. When c is already in d, the program assigns d[c] = d[c] + 1 because the character has appeared again.

Code walkthrough
d = {}
for c in "brontosaurus":
    if c not in d:
        d[c] = 1
    else:
        d[c] = d[c] + 1
  1. 1
    d = {} creates the dictionary that will store character counts.
  2. 2
    The for statement examines each character in the word.
  3. 3
    The condition c not in d tests whether the character is new.
  4. 4
    The initialization d[c] = 1 records the first occurrence.
  5. 5
    The else branch increases the count when the character has already been recorded.
  • Start with an empty dictionary.
  • Process one character c at a time.
  • Create a count of 1 for a character not yet in d.
  • Increase the existing count for a character already in d.
Current charactercCharacter in d?Count 1d[c] = 1Increase countd[c] = d[c] + 1checknoyes
How does the program decide whether to create a new count or increase an existing one?

A Character-by-Character Trace

The dictionary begins empty. Processing the first character, b, creates the entry b: 1. The next character, r, is new, so r: 1 is added. When the loop reaches another character that is already present, the program does not create a second key; it increments the value attached to the existing key.

Character processedReasonDictionary after processing
bb is new, so initialize its count{b: 1}
rr is new, so initialize its count{b: 1, r: 1}
oo is new, so initialize its count{b: 1, r: 1, o: 1}
nn is new, so initialize its count{b: 1, r: 1, o: 1, n: 1}
tt is new, so initialize its count{b: 1, r: 1, o: 1, n: 1, t: 1}
oo already exists, so increment its count{b: 1, r: 1, o: 2, n: 1, t: 1}

State trace for the first six characters of brontosaurus

Start{}b{b: 1}r{b: 1, r: 1}o{b: 1, r: 1, o: 1}n{b: 1, r: 1, o: 1, n: 1}t{b: 1, r: 1, o: 1, n: 1, t:1}o{b: 1, r: 1, o: 2, n: 1, t:1}process bprocess rprocess oprocess nprocess tprocess o again
How does the dictionary change after each character in the string is examined?

What do you think happens?

After processing b, r, o, n, t, and o from brontosaurus, what should the count for o be?

  • 0

  • 1

  • 2

Reveal answer
Answer:

2

The first o creates the entry with count 1. The later o finds that existing entry and increments it to 2.

The Concise get Method

The dictionary get method combines the two conditional cases. The expression d.get(c, 0) returns the current count when c is already a key. If c is not a key, it returns the supplied default value 0. Adding 1 and storing the result in d[c] therefore initializes a new character to 1 or increments an existing count.

python
Notes on the code
  • d.get(c, 0) retrieves the current count or supplies 0 when c is missing.
  • Adding 1 creates the first count or increases the existing count.
  • The result is stored back under key c.
Worked example

Reading d.get(c, 0) + 1

Explain what happens when the current character is new and when it has already been counted.

  1. 1
    New character

    If c is not in d, d.get(c, 0) returns 0. Adding 1 gives 1, which is stored as d[c].

  2. 2
    Existing character

    If c is already in d, d.get(c, 0) returns its current count. Adding 1 increases that count, and the new value is stored as d[c].

  3. 3
    Same final behavior

    Both cases update the dictionary with the correct count for the current character.

Result

The get method handles initialization and incrementing in one expression.

Conditionalapproachcheck, then initialize orincrementCharacter countssame final dictionaryget approachdefault 0, then add 1producesproduces
How do the conditional and get approaches differ in steps while producing the same final dictionary?

Choosing a Clear Approach

ApproachHow it handles a new characterHow it handles an existing characterMain characteristic
ConditionalSets d[c] to 1Adds 1 to d[c]More explicit and easier for beginners to follow
get methodUses default 0, then adds 1Retrieves the current count, then adds 1More concise and widely used in practice

Both approaches iterate through the string and produce identical character counts.

  • Common mistake

    Initializing an existing character instead of incrementing it

    What it looks like

    When o appears for the second time, setting d[o] = 1 would replace its previous count.

    Why it fails

    The dictionary must preserve the earlier count so repeated characters accumulate.

    Do this instead

    Check whether the key exists and increment d[o], or use d[o] = d.get(o, 0) + 1.

  • Common mistake

    Incrementing a character before giving it an initial count

    What it looks like

    Trying to increase d[c] when c is not yet a key.

    Why it fails

    A new character has no existing count to increase in the conditional approach.

    Do this instead

    Initialize a new key to 1, or let get supply 0 before adding 1.

  • Common mistake

    Assuming the two approaches produce different results

    What it looks like

    Treating the if-else version and the get version as separate counting rules.

    Why it fails

    Both handle a missing key as a count of 0 before the current occurrence is added.

    Do this instead

    Compare the final dictionaries: the approaches produce identical results.

Practice the State Change

MEDIUM

Trace the conditional approach for the first five characters of brontosaurus. Write the dictionary after each character is processed, and identify which character causes an increment rather than an initialization.

Hints
  • Begin with an empty dictionary.
  • The first occurrence of a character creates a count of 1.
  • The repeated character among the first five characters determines whether an increment occurs.
MEDIUM

Rewrite the conditional counting logic as the single get-method assignment d[c] = d.get(c, 0) + 1. Then explain why the default value must be 0 rather than 1.

Hints
  • The default represents the count before the current character is added.
  • Adding 1 to the default should produce the first occurrence count.

Key Takeaways

  1. 1
    A dictionary stores each unique character as a key and its count as the associated value.
  2. 2
    The conditional approach initializes a new character to 1 and increments an existing character by 1.
  3. 3
    The get method uses a default value of 0 so one expression can handle both new and existing characters.
  4. 4
    The conditional and get approaches produce identical results.
  5. 5
    Tracing the dictionary after every character makes initialization and incrementing visible.

At a glance

  • Character counting uses a dictionary to map each unique character to its count.
  • A character is initialized with count 1 the first time it appears.
  • A character's existing count is incremented each time it appears again.
  • The conditional approach and d[c] = d.get(c, 0) + 1 are equivalent.
  • Tracing dictionary state one character at a time reveals exactly how the histogram is built.

Related concepts

More concepts starting with B