Section 1 · Python Essentials for Analysts
Lists and Dictionaries
18 min3 min readPython exercise
Lesson at a glance
Hold many values in lists, look records up by key in dictionaries, and see how a list of dictionaries is already a small table.
No video here — just the real thing: a written lesson, runnable examples, a quiz and practice.
One variable per value stops working the moment you have twelve months of revenue, or forty-eight products. Python’s two workhorse containers solve this: the list, for values in order, and the dictionary, for values you look up by name. Between them they cover almost every data shape you will meet before pandas takes over.
Lists: values in order
Here is Cartwheel’s 2025 revenue by month, in dollars, January first:
monthly_2025 = [16167, 14906, 18208, 18817, 17428, 13933,
22968, 32042, 25514, 30339, 75334, 41153]
print(len(monthly_2025)) # 12 items
print(monthly_2025[0]) # January: positions start at 0
print(monthly_2025[-1]) # December: negative positions count from the end
print(sum(monthly_2025), max(monthly_2025), min(monthly_2025))Positions (indexes) start at 0, so the twelfth month is at position 11. Asking for monthly_2025[12] raises IndexError: list index out of range.
Slicing
A slice items[start:stop] takes a run of items. The start is included and the stop is excluded, which feels odd for a day and then becomes convenient: [0:3] is exactly three items.
monthly_2025 = [16167, 14906, 18208, 18817, 17428, 13933,
22968, 32042, 25514, 30339, 75334, 41153]
q1 = monthly_2025[0:3] # Jan, Feb, Mar
q4 = monthly_2025[-3:] # last three: Oct, Nov, Dec
print(q1, sum(q1))
print(q4, sum(q4))
print(sorted(monthly_2025)[:3]) # the three weakest monthsQ4 brought in 146,826 dollars against 49,281 in Q1: three times as much. That gap is the question this course will eventually answer, and a two-line slice was enough to see it.
Changing a list
Lists are mutable: you can change them in place. append() adds to the end, and assignment to a position replaces an item.
months = ["Jan", "Feb", "Mar"]
months.append("Apr")
months[0] = "January"
print(months, "Mar" in months)The in operator asks whether a value is present and returns True or False.
Because lists are mutable, two names can share one list. backup = months attaches a second name to the same list, so changing one changes “both”. When you really need an independent copy, write months.copy().
Dictionaries: values you look up by key
A dictionary stores key: value pairs. Keys are usually strings; values can be anything.
product = {
"product_id": 7,
"name": "Burr Coffee Grinder",
"unit_price": 129,
"is_active": True,
}
print(product["name"]) # look up by key
product["unit_price"] = 135.45 # update after the 5% price rise
product["category"] = "Coffee & Tea" # add a new key
print(product)
print(product.get("launched_on", "unknown"))product["launched_on"] would crash with KeyError: 'launched_on'. .get() returns a default instead. Use square brackets when a missing key is a bug you want to hear about, and .get() when missing is normal.
Three methods let you walk through a dictionary: .keys(), .values() and .items() (pairs). You will use .items() with loops in the next lesson.
A list of dictionaries is a table
Put several dictionaries with the same keys into a list and you have rows and columns:
order_lines = [
{"order_id": 1000, "product": "Foam Roller", "quantity": 2, "unit_price": 27.3},
{"order_id": 1001, "product": "Solar Path Lights (6)", "quantity": 2, "unit_price": 44.1},
{"order_id": 1001, "product": "Burr Coffee Grinder", "quantity": 2, "unit_price": 135.45},
]
print(len(order_lines), "rows")
print(order_lines[1]["product"]) # row 1, column "product"order_lines[1]["product"] reads like a spreadsheet cell reference: row first, then column.
The other table shape: a dictionary of lists
You can also store a table the other way round: one key per column, each holding a list of that column’s values.
order_lines = {
"order_id": [1000, 1001, 1001],
"product": ["Foam Roller", "Solar Path Lights (6)", "Burr Coffee Grinder"],
"quantity": [2, 2, 2],
}
print(order_lines["product"]) # a whole column at once
print(sum(order_lines["quantity"]))Rows are easy to read in the list-of-dicts shape; columns are easy to total in the dict-of-lists shape. Both shapes show up in real life: APIs and JSON files usually hand you a list of records, while people building a small table by hand often write it column by column. pandas accepts both, and you will build your first DataFrame from a dictionary of lists in the next section.
This is the bridge to pandas. A DataFrame is a far more capable version of this table: it can sum a whole column at once, filter rows by a condition and read a CSV in one call. Learning lists and dictionaries first means you will understand what pandas is doing for you, and you will recognise the list-of-dicts shape when an API or a JSON file hands you data.
In the exercise you slice the monthly list and update a price dictionary. Next, loops and conditions let you process every item without writing one line per item.
Key takeaways
- Lists are ordered and indexed from 0;
items[-1]is the last item anditems[a:b]stops before positionb. sum(),len(),max(),min()andsorted()work on any list of numbers and answer most quick questions.- A dictionary maps keys to values; use
d[key]when the key must exist andd.get(key, default)when it might not. - A list of dictionaries with the same keys is a table, one dictionary per row, which is exactly what a DataFrame generalises.