Lines with several values
Often each line of a file holds several pieces of data about one thing: a name, an age and a city, say. A common format for this is CSV, short for comma-separated values. Each line is one record, and a separator character, usually a comma , or a semicolon ;, separates its fields. Spreadsheet programs can save and open CSV files, which makes them a common way to move data from one program to another.
Splitting a string
To get the fields of a line, use the string method split, which you have met in the module on strings and lists. It cuts a string at each separator and returns the pieces as a list of strings. You give it the separator as a string:
>>> "Rex;dog;4".split(";")
['Rex', 'dog', '4']
>>> "red,green,blue".split(",")
['red', 'green', 'blue']
>>> parts = "Rex;dog;4".split(";")
>>> parts[0]
'Rex'
>>> int(parts[2]) + 1
5
>>> "cats and dogs".split()
['cats', 'and', 'dogs']The separator itself isn't in any of the pieces. The pieces are always strings, even when they look like numbers: convert them with int or float before you calculate with them. (And remember that without an argument, split() splits at spaces, however many there are in a row.)
A CSV file, line by line
Rex;dog;4
Misty;cat;11
Bubbles;fish;1with open("pets.csv") as file:
for line in file:
parts = line.strip().split(";")
name = parts[0]
animal = parts[1]
age = int(parts[2])
if age >= 10:
print(f"{name} the {animal} is a senior, {age} years old")
else:
print(f"{name} the {animal} is {age} years old")
Rex the dog is 4 years old
Misty the cat is a senior, 11 years old
Bubbles the fish is 1 years oldline.strip().split(";") first removes the line break and then splits. Without the strip, the last field would keep the line break, ['Rex', 'dog', '4\n']. int happens to accept that, but a text field at the end of the line, such as a city, would carry its \n into everything you do with it.
Headers and extra spaces
Many CSV files start with a header line that names the columns, and some have a space after each separator. In this file each line has a player, a team and the points from any number of rounds:
player; team; round 1; round 2; round 3
Maya; Owls; 12; 9; 15
Leo; Foxes; 8; 14; 10with open("rounds.csv") as file:
for line in file:
parts = line.split(";")
if parts[0] == "player":
continue
name = parts[0]
team = parts[1].strip()
points = []
for part in parts[2:]:
points.append(int(part))
print(f"{name} ({team}): {points}, total {sum(points)}")
Maya (Owls): [12, 9, 15], total 36
Leo (Foxes): [8, 14, 10], total 32- The header is recognized by its first field and skipped with
continue. parts[1]is" Owls"with a space in front, so it gets its ownstrip().- The numbers need no stripping, because
intignores spaces and a line break around a number. - The slice
parts[2:]is every field from the third one on, so the same code works however many rounds a line has.