๐Ÿ“– Python Dictionaries and Bad Vexillology Design#

In this notebook, we will explore Python dictionaries using the theme of bad vexillology (flag design). Weโ€™ll use examples of poorly designed flags to understand dictionary concepts, methods, advantages, and limitations.

Bad Flag Design Elements#

  • Too Complex: Intricate designs or details that are hard to see and replicate.

  • Cluttered: Overloaded with symbols, colors, or themes.

  • Poor Colors: Clashing, low-contrast, or overly similar colors.

  • Text: Words or slogans that are unreadable when waving.

  • No Symbolism: Random imagery with no clear meaning.

San Francisco Flag#

San Francisco Flag

bad_flag = {
    "country": "Confusistan",
    "colors": ["red", "green", "purple", "neon yellow"],
    "symbols": ["star", "dragon", "rainbow", "text: 'Unity'"],
    "design_complexity": "Extremely High",
    "readability": "Unreadable",
}
print("Bad Flag Example:")
print(bad_flag)
Bad Flag Example:
{'country': 'Confusistan', 'colors': ['red', 'green', 'purple', 'neon yellow'], 'symbols': ['star', 'dragon', 'rainbow', "text: 'Unity'"], 'design_complexity': 'Extremely High', 'readability': 'Unreadable'}

Definition and Syntax#

Milwaukee Flag#

Milwaukee Flag

Definition

A dictionary is an ordered, mutable collection of key-value pairs in Python. Keys must be unique and immutable, while values can be any type.

Syntax

d = {"key1": value1, "key2": value2} Examples:

  • { "name": "White House", "location": "Beijing" }

  • { 1: "one", 2: "two", 3: "three" }

  • { "x": 42, "y": 3.14 }

Note

Dictionaries in Python were unordered before version 3.7. Since Python 3.7, dictionaries maintain the insertion order.

Updating Dictionary Elements#

You can update key-value pairs using the = assignment operator. Where the variable is the dictionary and the new key is in square brackets.

You can also use the update() method to add multiple key-value pairs to a dictionary.

bad_flag["controversy"] = "Offensive design choices"
print("\nUpdated Bad Flag Dictionary:")
print(bad_flag)
Updated Bad Flag Dictionary:
{'country': 'Confusistan', 'colors': ['red', 'green', 'purple', 'neon yellow'], 'symbols': ['star', 'dragon', 'rainbow', "text: 'Unity'"], 'design_complexity': 'Extremely High', 'readability': 'Unreadable', 'controversy': 'Offensive design choices'}

Note

in a string \ is used as an escape character. This means that it is used to represent characters that are not allowed in the string. For instance, the single quote character (โ€™) is not allowed in a string delineated by single quotes. If you want to include a single quote character in a string delineated by single quotes, you must use the escape character like this: โ€˜, in the previous example we used \n which is used to represent a new line.

Extracting Values#

You can extract values from a dictionary using the key in square brackets.

print("\nAccessing a value:")
print("Colors in the flag:", bad_flag["colors"])
Accessing a value:
Colors in the flag: ['red', 'green', 'purple', 'neon yellow']

Adding a New Key-Value Pair#

You can add a new key-value pair to a dictionary by assigning a value to a new key.The variable is the dictionary and the new key is in square brackets.

bad_flag["public_opinion"] = "Negative"
print("\nAdding a new key-value pair for 'public_opinion':")
print(bad_flag)
Adding a new key-value pair for 'public_opinion':
{'country': 'Confusistan', 'colors': ['red', 'green', 'purple', 'neon yellow'], 'symbols': ['star', 'dragon', 'rainbow', "text: 'Unity'"], 'design_complexity': 'Extremely High', 'readability': 'Unreadable', 'controversy': 'Offensive design choices', 'public_opinion': 'Negative'}

Removing a Key-Value Pair#

You can remove a key-value pair from a dictionary using the pop() method. The key is passed as an argument to the method.

bad_flag.pop("controversy")
print("\nRemoving the 'controversy' key:")
print(bad_flag)
Removing the 'controversy' key:
{'country': 'Confusistan', 'colors': ['red', 'green', 'purple', 'neon yellow'], 'symbols': ['star', 'dragon', 'rainbow', "text: 'Unity'"], 'design_complexity': 'Extremely High', 'readability': 'Unreadable', 'public_opinion': 'Negative'}

Getting All Keys and Values#

You can get all keys and values from a dictionary using the keys() and values() methods, respectively.

print("\nGetting all the keys:")
print("Keys:", bad_flag.keys())

print("\nGetting all the values:")
print("Values:", bad_flag.values())
Getting all the keys:
Keys: dict_keys(['country', 'colors', 'symbols', 'design_complexity', 'readability', 'public_opinion'])

Getting all the values:
Values: dict_values(['Confusistan', ['red', 'green', 'purple', 'neon yellow'], ['star', 'dragon', 'rainbow', "text: 'Unity'"], 'Extremely High', 'Unreadable', 'Negative'])

Limitations on Keys and Values#

Philadelphia Flag#

Syntax

Key Limitations

  • Keys must be unique. If a key is duplicated, the last value assigned to it will overwrite earlier values.

  • Keys must be immutable types: Examples include strings, numbers, and tuples. Mutable types (e.g., lists, sets) cannot be used as keys.

Examples:

  • Valid keys: "name", 42, (1, 2)

  • Invalid keys: [1, 2, 3], { "key": "value" }

Syntax

Value Limitations

  • Values can be any type, but their mutability affects how the dictionary behaves.

  • Nested mutable types (e.g., lists or dictionaries) can cause unintentional side effects if modified directly.

Examples:

  • Valid values: "string", [1, 2, 3], { "nested": "dict" }

  • Caution with mutable values: Modifying bad_flag["colors"] affects the dictionary directly.

try:
    invalid_key_dict = {[1, 2, 3]: "Invalid"}
except TypeError as e:
    print("\nExample of Invalid Key Error:", e)

Nested Dictionaries#

You can nest dictionaries within dictionaries to create more complex data structures. This is useful for representing hierarchical relationships or structured data. This is done by assigning a dictionary as a value to a key in another dictionary.

Note

Nested dictionaries are the foundation of JSON (JavaScript Object Notation), a popular data interchange format. Nearly everything on the web is transmitted as JSON, including API responses, configuration files, and more. Even this courses grades are stored in a JSON and transmitted via JSON.

nested_dict = {"flag_details": bad_flag}
nested_dict["flag_details"]["colors"].append("gold")
print("\nModified Nested Dictionary (caution with mutable values):")
print(nested_dict)
Modified Nested Dictionary (caution with mutable values):
{'flag_details': {'country': 'Confusistan', 'colors': ['red', 'green', 'purple', 'neon yellow', 'gold'], 'symbols': ['star', 'dragon', 'rainbow', "text: 'Unity'"], 'design_complexity': 'Extremely High', 'readability': 'Unreadable', 'public_opinion': 'Negative'}}

Advantages of Dictionaries#

  • Fast lookups: Average time complexity is \(O(1)\).

  • Flexible: Can store structured, nested data.

  • Dynamic: Keys and values can be added or removed on the fly.

  • Efficient: Memory-efficient for large datasets.

Limitations of Dictionaries#

  • Keys must be unique and immutable.

  • Higher memory usage: Requires more memory compared to other data structures like lists.

  • Unordered in older Python versions: Dictionaries do not maintain order prior to Python 3.7.

Practical Example: Evaluating Flags#

flag_evaluation = {
    "Confusistan": {"colors": 10, "symbols": 5, "readability": 1},
    "Rainbowland": {"colors": 7, "symbols": 3, "readability": 5},
    "Clashopolis": {"colors": 2, "symbols": 1, "readability": 9},
}

print("\nFlag Evaluation Scores:")

# we will learn about using dictionary with for loops later in the course.
for flag, scores in flag_evaluation.items():
    complexity_score = sum(scores.values())
    print(f"{flag} total score: {complexity_score}")
Flag Evaluation Scores:
Confusistan total score: 16
Rainbowland total score: 15
Clashopolis total score: 12

๐Ÿ˜ž

Digression: My favorite flag is the Chicago flag. Itโ€™s simple, meaningful, and iconic. Itโ€™s a great example of good flag design. Now not only are you a Python Dictionary expert, but you also are a budding vexillologist!

Chicago Flag