Python Arena
Step 5 of 5

Combining data from several files

Data that belongs together is often spread over several files. A shop might keep its product names in one file and the amounts in stock in another, because different people update them. What connects the files is a shared key: a value, such as a product code, that appears in both and means the same thing in each.

The usual way to combine such files is to read each one into a dictionary with the key as the dictionary's key, and then look the keys up:

The file products.csv
code;name
P1;desk lamp
P2;office chair
P3;bookshelf
The file stock.csv
code;amount
P2;14
P1;3
names = {}
with open("products.csv") as file:
    for line in file:
        parts = line.strip().split(";")
        if parts[0] == "code":
            continue
        names[parts[0]] = parts[1]

amounts = {}
with open("stock.csv") as file:
    for line in file:
        parts = line.strip().split(";")
        if parts[0] == "code":
            continue
        amounts[parts[0]] = int(parts[1])

for code, name in names.items():
    if code in amounts:
        print(f"{name}: {amounts[code]} in stock")
    else:
        print(f"{name}: none in stock")
Output
desk lamp: 3 in stock
office chair: 14 in stock
bookshelf: none in stock

Notice two things. The lines of the two files are in a different order, and that doesn't matter, because the dictionary finds each code wherever it was in the file. And P3 has no line in stock.csv at all: the in check handles that, where amounts[code] alone would stop the program with a KeyError.

One function, several files

When two files have the same shape, one function can read both. Programs also often ask the user which files to read, instead of having the names in the code:

The file names.csv
101;Ana
102;Bo
103;Cy
The file emails.csv
103;cy@example.com
101;ana@example.com
def read_pairs(filename):
    pairs = {}
    with open(filename) as file:
        for line in file:
            parts = line.strip().split(";")
            pairs[parts[0]] = parts[1]
    return pairs


names = read_pairs(input("Names file: "))
emails = read_pairs(input("Emails file: "))
for number, name in names.items():
    if number in emails:
        print(f"{name}: {emails[number]}")
    else:
        print(f"{name}: no email")
Input
names.csv
emails.csv
Output
Names file: names.csv
Emails file: emails.csv
Ana: ana@example.com
Bo: no email
Cy: cy@example.com

The student numbers stay strings here: they are only compared with each other, never calculated with, so there's no need to convert them.

Many lines with the same key

Sometimes a file has many lines for the same key, such as one line for every sale of a product. Then the dictionary can collect a total for each key: the first time a key comes up, its total starts at 0, and every line adds to it.

totals = {}
with open("sales.csv") as file:
    for line in file:
        parts = line.strip().split(";")
        code = parts[0]
        if code not in totals:
            totals[code] = 0
        totals[code] += int(parts[1])

Your task

Challenge 1 of 3

The file prices.csv has the price of each item in a shop, and cart.csv has the items in a customer's cart and how many of each. Fill in the blank so the program prints the total price of the cart. With these files

apple;0.40
bread;2.10
milk;1.15
bread;1
apple;6
milk;2

the program prints:

Total: 6.80

Challenge 2

A climbing gym keeps its members in one file (number;name) and every visit in another (number;date, one line per visit). Write a program that asks for the names of the two files and prints each member's name and number of visits, in the order of the members file. Members who haven't visited get 0.

With these files, members.csv and visits.csv

1;Ana
2;Bo
3;Cy
3;2026-03-02
1;2026-03-02
1;2026-03-05
1;2026-03-09

a run looks like this:

Members: members.csv
Visits: visits.csv
Ana 3
Bo 0
Cy 1

Challenge 3

A football league has two files, each with a header line. players.csv tells which team each player is in (player;team), and goals.csv has a line for each match in which a player scored (player;goals). Write a function team_goals(players_file, goals_file) that returns a dictionary from each team to its total goals. Every team of the players file is in it, in the order the teams first appear there, also a team whose players scored nothing.

With these files

player;team
Ana;Owls
Bo;Foxes
Cy;Owls
Dee;Bears
player;goals
Ana;2
Cy;1
Ana;1
Bo;3

print(team_goals("players.csv", "goals.csv")) prints:

{'Owls': 4, 'Foxes': 3, 'Bears': 0}