ailiteracynepal 🇳🇵
Text size

Chapter 02 · Section I · 26 min read

The data shapes: lists, dictionaries, and tables

Three shapes account for almost every piece of data you will work with in this track. Get comfortable with them now and most real code becomes legible.

In the last chapter you stored a name and a greeting in two separate variables. That works when you have two things. When you have two hundred — two hundred Khalti transactions, two hundred days of NEPSE prices, two hundred student records — you need a shape to hold them in. Most real programs are mostly about choosing the right shape and then moving data through it.

The three shapes that cover almost everything

There are exactly three you will use over and over:

  1. A list — an ordered sequence of items.
  2. A dictionary — a set of named properties.
  3. A list of dictionaries — a table. A collection of things, each with named properties.

Almost every dataset in this track collapses into one of those three. Learn them once carefully and the rest of the track speeds up.

A list

A list is what it sounds like. An ordered sequence. You write it with square brackets and commas:

expenses = [120, 80, 250, 90, 45]

Now expenses holds five numbers. A few useful operations:

expenses[0]        # 120 — the first item
expenses[-1]       # 45  — the last item
len(expenses)      # 5   — how many items
expenses.append(300)   # adds 300 to the end
expenses[1:3]      # [80, 250] — items from index 1 up to (not including) 3

A few things worth carrying with you:

  • Lists are zero-indexed. The first item is expenses[0], not expenses[1]. This trips up almost everyone for a week. The world is wrong; programming languages mostly agree on starting from zero.
  • You can hold anything in a list — numbers, strings, other lists, mixed types. Most real-world lists hold one kind of thing.
  • len(...) tells you how many. .append(...) adds to the end. These two and zero-indexing get you through 80% of list work.

A dictionary

A dictionary holds named properties of a single thing. Curly braces, key-value pairs, separated by commas:

transaction = {
    "vendor": "Khalti",
    "amount": 5000,
    "date": "2026-06-25",
    "approved": True,
}

You access values by key, not by position:

transaction["vendor"]    # "Khalti"
transaction["amount"]    # 5000

You can add or change values by assignment:

transaction["status"] = "settled"
transaction["amount"] = 5050

The right time to reach for a dictionary is when a single thing has several named pieces — a person has a name and an age and a district; a transaction has a vendor and an amount and a date. If you find yourself writing three variables that all describe the same thing — vendor, amount, date — that is a dictionary trying to happen.

A list of dictionaries: the table shape

This is the single most useful shape in all of data work. It is what almost every real dataset is, before someone wraps it in a fancier name:

transactions = [
    {"vendor": "Khalti",   "amount": 5000, "date": "2026-06-25"},
    {"vendor": "eSewa",    "amount": 1200, "date": "2026-06-25"},
    {"vendor": "Khalti",   "amount":  450, "date": "2026-06-26"},
    {"vendor": "FonePay",  "amount":  900, "date": "2026-06-26"},
]

This is a table. Each dictionary is a row. The keys (vendor, amount, date) are the columns. It is the same shape as a spreadsheet, the same shape as a NEPSE export, the same shape as a CSV file you will read in Section 3.

Once you have it, common questions are easy to ask. To list every vendor:

for t in transactions:
    print(t["vendor"])

To total all amounts:

total = 0
for t in transactions:
    total = total + t["amount"]
print(total)   # 7550

You will write code shaped like this every week for the rest of the track.

A quick comparison

A small table to keep straight:

ShapeUse it forExample
ListAn ordered sequence of similar items[120, 80, 250] — five expenses
DictionaryNamed properties of a single thing{"vendor": "Khalti", "amount": 5000}
List of dictionariesA collection of things, each with named propertiesOne row per transaction

If you ever feel stuck choosing a shape, ask: am I holding a sequence, a single thing’s properties, or a collection of such things?

A worked piece of code to read carefully

Before the quiz, one small program to sit with. It uses all three shapes:

transactions = [
    {"vendor": "Khalti",  "amount": 5000},
    {"vendor": "eSewa",   "amount": 1200},
    {"vendor": "Khalti",  "amount":  450},
    {"vendor": "FonePay", "amount":  900},
]

vendors = []
for t in transactions:
    vendors.append(t["vendor"])

print(vendors)

Predict the output before you run it.

The expected output is:

['Khalti', 'eSewa', 'Khalti', 'FonePay']

Read it once more. The list of dictionaries is the input. The list of strings is the output. The dictionary access (t["vendor"]) and the list append (vendors.append(...)) are the two operations that move data from one shape to the other. This is the rhythm of almost every data-shaping task in this track.

Check your understanding

Quick check

A friend writes this program: prices = [200, 180, 220, 190] print(prices[1]) What does it print?

Quick check

You have this data: people = [ {'name': 'Anu', 'district': 'Kaski'}, {'name': 'Bikas', 'district': 'Morang'}, ] Which expression gives the string 'Morang'?

What comes next

You now have shapes to hold data in. The next section gives you the tools to move data through them: functions to give a piece of work a name, and loops to do the same work many times without copy-pasting. The two together turn a list of dictionaries into something you can compute on.