EduFlow

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.

  1. 1Lists: values in order
  2. 2Dictionaries: values you look up by key
  3. 3A list of dictionaries is a 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:

Python
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.

Python
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 months

Q4 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.

Python
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.

Python
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:

Python
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.

On the left, a list holds three dictionaries, each with keys order_id, product and quantity. On the right, the same data drawn as a table: each dictionary becomes a row and each key becomes a column header. list of dicts {order_id: 1000, product: ..., qty: 2} {order_id: 1001, product: ..., qty: 2} {order_id: 1001, product: ..., qty: 2} table (DataFrame) order_id product qty 1000 Foam Roller 2 1001 Solar Lights 2 1001 Grinder 2 each dict is a row; each key is a column
The same three order lines as a list of dictionaries and as a table

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.

Python
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 and items[a:b] stops before position b.
  • sum(), len(), max(), min() and sorted() 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 and d.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.

Further reading

Check your understanding

4 questions

Question 1 of 4

monthly holds 12 monthly totals, January first. Which expression is the total for April, May and June?

Question 2 of 4

prices = {"Desk Mat XL": 29}. What does prices.get("Monitor Arm", 0) return?

Question 3 of 4

What does this print?

Python
totals = [65, 18, 33]
backup = totals
totals.append(35)
print(len(backup))
Question 4 of 4

You need the price of a product by name, thousands of times. Which structure fits best?

Practice

Python exercise

Slice the year and update prices

Using the monthly_2025 and months lists and the prices dictionary: set q4_total to the sum of October to December using a slice; set best_month to the three-letter name of the month with the highest revenue; add "Laptop Stand" to prices at 49; and set grinder_new_price to the Burr Coffee Grinder’s price after a 5% rise, rounded to 2 decimals. Work it out with code rather than typing the numbers.

monthly_2025 = [16167, 14906, 18208, 18817, 17428, 13933,
                22968, 32042, 25514, 30339, 75334, 41153]
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

prices = {"Cast Iron Skillet 26cm": 39, "Burr Coffee Grinder": 129, "Cork Yoga Mat": 72}

# 1. Q4 total (October, November, December) using a slice
q4_total = None

# 2. Name of the month with the highest revenue, e.g. "Mar"
best_month = None

# 3. Add "Laptop Stand" to prices at 49

# 4. The grinder's price after a 5% rise, rounded to 2 decimals
grinder_new_price = None
Loading the editor…

Ctrl/⌘ + Enter to run · Runs in a sandbox in your browser. Nothing leaves your device.

(no output)

Checks

  • q4_total is 146,826
  • best_month is "Nov"
  • prices now has 4 products, including Laptop Stand at 49
  • grinder_new_price is 135.45
  • The original lists still have all 12 months