Python Data Structures: Dictionaries, Sets, Lists, and F-Strings

Overview of the session

The transcript covers core Python data structures (lists, dictionaries, and sets) and how to build practical data models by combining them. It also explains string formatting, especially the use of f-strings for dynamic content, and demonstrates a classroom-style workflow for collecting and organizing student data (names, number of courses, and the list of courses). The instructor emphasizes how to access, modify, and display data, and how these concepts connect to real-world tasks like building a roster or a course list. Several concrete examples are used: selecting a number of courses from a named instructor, formatting strings with dynamic values, creating dictionaries with keys and values, using sets to remove duplicates, and constructing a list of dictionaries to represent multiple students.

String formatting and the f-format (f-strings)

  • The teacher differentiates between static strings and dynamic content inside a string. When dynamic data is needed inside a string, you insert placeholders inside curly braces, which are then evaluated and replaced at runtime.

  • This is referred to as the string format or f-format. An example concept shown: the placeholder inside the string is replaced by the corresponding variable or expression.

  • The curly braces act as dynamic placeholders. If you want to insert a number or a variable, you place it inside the braces, like {variable}.

  • When numerical or textual data is inserted dynamically, the surrounding string remains a normal string; the embedded expression is evaluated and converted to text as needed.

  • The discussion includes how to handle dynamic data (variables) versus static data. For example, a static value such as 6 will remain 6, but a variable value can change depending on user input. Using a dynamic approach requires curly braces for the variable inside the f-string, so the value can change each time the string is generated.

  • A practical pattern mentioned is to use 0-based indices for internal logic (e.g., lists) and adjust to 1-based display when presenting to users. The math behind this is simple: if i is a 0-based index, the displayed number is extdisplayedextnum=i+1,ag1ext{displayed ext{num}} = i + 1, ag{1} where i{0,1,2,}).i \in \{0,1,2,…\}).

  • The instructor also notes that any data type can be embedded inside an f-string as long as it can be coerced to a string for display.

Dictionaries: structure, creation, access, and updates

  • A dictionary in Python is a mapping from keys to values, defined with curly braces or via the dict() constructor. Keys and values are organized as key: value pairs, separated by commas.

  • Important: curly braces denote a dictionary; a set uses curly braces too, but without colons. An empty dictionary is {}, while an empty set is created with set().

  • Example concepts from the transcript:

    • A dictionary is created as an empty dict with {}; or using dict() to create an empty dictionary.

    • A key can be of any hashable type (e.g., strings, integers); the value can be any type (string, number, another dictionary, list, etc.).

    • Each entry in a dictionary is a key-value pair. Keys must be unique within a dictionary.

  • Accessing data:

    • To retrieve a value, use d[key]. For example, car["brand"] returns the brand value.

    • You can list all keys with d.keys(), all values with d.values(), and all key-value pairs with d.items().

    • The get() method can retrieve a value with a default if the key is missing: d.get(key, default).

  • Updating data:

    • If you assign to an existing key, the old value is replaced: D[k] = v.

    • To add a new key-value pair, you provide a new key and its value: D[newkey] = newvalue.

    • You can update multiple keys at once using the update() method: D.update({k1: v1, k2: v2}) or D.update([(k, v), …]).

  • Examples discussed in the transcript:

    • A car dictionary with keys such as brand, model, and year demonstrates typical access patterns: car["brand"], car["model"], car["year"].

    • Listing keys: car.keys() returns all the keys; printing helps you inspect the structure.

    • Keys can be of mixed types (e.g., a string key and an integer key both mapping to values).

    • A dictionary can be nested; for example, a person dictionary with keys like 'name' and 'age' can contain values that are other dictionaries or lists.

  • Special cases and common questions:

    • You can have a key without an immediately visible value in function-like contexts, but in a literal dictionary, a missing value isn’t valid syntax; placeholders are typically filled with None if you need a placeholder: {"name": None}.

    • Dictionaries vs dot notation: dictionaries are accessed with square brackets and string keys (e.g., car["brand"]). There is no dot notation for raw dictionary keys unless you convert to an object with attributes.

    • Keys must be unique within a dictionary. If you assign a new value to an existing key, the previous value is replaced.

  • Reading and constructing dictionaries: an example car-like dictionary might be {"brand": "Ford", "model": "Mustang", "year": 2015}. Iteration over keys and values can use d.keys(), d.values(), and d.items().

  • Practical note: when you want to input data at runtime (e.g., from user input), you can construct dictionaries by asking for a key and a value and then performing D[key] = value. If you want to add many items at once, you can use update with another dictionary.

  • The idea of using dictionaries to group related data (a car, a student, etc.) is to create a mapping that you can easily access by a meaningful key, rather than relying on index positions as with lists.

Sets: removing duplicates and understanding the difference from dictionaries

  • A set is an unordered collection of unique elements. It does not allow duplicates by design.

  • Sets can be created via set([elements]) or using curly braces with comma-separated values for non-empty sets ({} is a dictionary, not a set).

  • Example demonstration in the transcript shows that converting a list with duplicates to a set removes duplicates: set([1, 5, 5, 5]) yields {1, 5}.

  • Practical consequence: sets are useful for deduplication, membership tests, and operations like unions, intersections, and differences. If you need to preserve order or maintain a mapping, you would not use a set alone.

  • The transcript highlights that a dictionary can be converted to a set of its keys: set(d) yields the set of keys from dictionary d.

Lists of dictionaries: modeling multiple entities (e.g., students)

  • The transcript describes building a list where each element is a dictionary representing a student with fields such as name and courses.

  • Example structure:

    • A top-level list: students = []

    • Each student is a dictionary: {"name": "Alice", "courses": ["Course A", "Course B"]}

  • How to populate this structure:

    • The outer list should be created once before entering the input loop; for each student, create a per-student dictionary and append it to the outer list.

    • For each student, gather the name and then a list of courses (which itself can be built by looping over the number of courses and appending to a per-student courses list).

    • After collecting a student's data, append the per-student dictionary to the list of students.

  • Example workflow (conceptual):

    • students = []

    • for each student in the input set:

    • name = input("Enter name: ")

    • courses = []

    • for i in range(num_courses):

      • course = input("Course: ")

      • courses.append(course)

    • student = {"name": name, "courses": courses}

    • students.append(student)

  • Accessing data in this structure:

    • Print all students: print(students)

    • Access a specific field (e.g., the first student’s name): students[0]["name"]

    • Access the first course of the second student: students[1]["courses"][0]

  • This approach demonstrates how to combine simple data types (strings, lists) inside dictionaries to model more complex real-world data.

Practical workflow and reflections from the classroom example

  • The instructor ties these concepts to a practical task: collecting and displaying information about students, including the number of courses each offers and the course names.

  • They discuss the idea of making a 1-based display for user-facing numbers while keeping 0-based indexing internally for logic, reinforcing the common pattern: internal (0-based) vs external (1-based) representation.

  • They emphasize that coding is about combining small, well-understood pieces (lists, dictionaries, sets, and strings) to solve larger problems. You can build complex data models by composing these primitives.

  • They present an example where a file is opened and data is read, then assembled into a dictionary with keys such as 'person' and 'age', demonstrating how to collect interactive input and store it in a nested structure.

  • The discussion about keys: in dictionaries, keys must be unique; attempting to insert a key that already exists will overwrite the old value. A dynamically built input loop should handle these cases carefully to avoid unintended overwrites.

  • The instructor also introduces the idea of updating multiple fields at once using the update() method, which can take a dictionary of key-value pairs and merge it into the existing dictionary.

  • Finally, the teacher hints at a larger, multi-student exercise (e.g., handling data for 20 students) and how to organize code to create and accumulate the data efficiently, encouraging the use of a list of dictionaries and ensuring data collection happens in a way that can be easily printed or stored.

Quick reference of key operations and syntax

  • Dictionary basics:

    • Create: d = {} or d = dict()

    • Add/update: d[key] = value

    • Access: value = d[key]

    • Safe access: value = d.get(key, default)

    • Keys, values, items: d.keys(), d.values(), d.items()

    • Update multiple keys: d.update({k1: v1, k2: v2})

  • Set basics:

    • Create: s = set([a, b, c]) or s = {a, b, c}

    • Deduplication effect: duplicates are removed automatically

    • Note: an empty set must be created with set(), not {}

  • Lists and nested data:

    • Lists hold ordered items and are index-based

    • A list of dictionaries can model multiple entities (e.g., students) with each dictionary representing one entity

  • String formatting:

    • f-strings: f"Hello {name}, you have {len(courses)} courses" demonstrates embedding expressions inside strings

    • Placeholders inside { } evaluate to their values at runtime

    • For numbers and text, Python converts to strings when formatting

  • Indexing conventions:

    • Internal indices are 0-based, but user-facing numbering can be 1-based: extdisplay=extindex+1ext{display} = ext{index} + 1

  • Real-world relevance and ethics:

    • Structured data (lists, dictionaries, sets) supports reproducible analysis, easier debugging, and scalable data collection for tasks like student rosters, course listings, and reporting.

    • Clear data organization reduces errors when handling multiple students and their courses, and supports future extension (e.g., adding more fields, exporting to JSON, etc.).

End-of-session recap and next steps

  • You should be able to create and manipulate dictionaries, including adding keys, updating values, and retrieving data.

  • You should understand how to use sets to remove duplicates and how to convert a dictionary to a set of its keys.

  • You should be able to assemble a list of dictionaries to model multiple entities (like students) and populate it with input data, then print or inspect the resulting structure.

  • As a next step, practice building a small project that collects several students’ names and their courses, stores them in a list of dictionaries, and then prints a summary for each student. Experiment with:

    • nested dictionaries and lists

    • using dict.update() to modify multiple fields at once

    • converting between lists, dictionaries, and sets for different tasks