Objects in lists and dictionaries
An object of a class you wrote can go anywhere a number or a string can: into a variable, a list, a dictionary or a function call. To Python, your classes are types just like the ones it has built in. 5 is an int, "hi" is a str, Song("Slow River", 302) is a Song, and all of them are objects. You have already kept your own objects in variables and lists and given them to functions. This part of the course looks at what really happens when you do, starting with lists and dictionaries of objects.
A list of objects
Here a playlist is a list of Song objects. The loop takes the songs one at a time, and song.title reaches the title of the song the loop is at:
class Song:
def __init__(self, title, seconds):
self.title = title
self.seconds = seconds
playlist = []
playlist.append(Song("Morning Light", 215))
playlist.append(Song("Slow River", 302))
playlist.append(Song("Neon Rain", 187))
total = 0
for song in playlist:
print(song.title)
total += song.seconds
print("Total length:", total, "seconds")
Morning Light
Slow River
Neon Rain
Total length: 704 secondsEach Song(...) call creates a new object, and append puts it at the end of the list. In the loop, song is a Song object, so everything a song has is there behind the dot.
Finding the right object
A function can look through a list of objects and return one of them. Returning the whole object, not just its title, lets the caller use whatever it needs from it:
class Song:
def __init__(self, title, seconds):
self.title = title
self.seconds = seconds
def __str__(self):
return f"{self.title} ({self.seconds} s)"
def longest(songs):
best = songs[0]
for song in songs:
if song.seconds > best.seconds:
best = song
return best
playlist = [Song("Morning Light", 215), Song("Slow River", 302), Song("Neon Rain", 187)]
winner = longest(playlist)
print(winner)
print("Title only:", winner.title)
Slow River (302 s)
Title only: Slow Riverbest starts as the first song and is replaced whenever a longer one comes along. The comparison is between song.seconds and best.seconds, two numbers. Comparing the songs themselves doesn't work, because Python has no idea what would make one song "greater" than another:
class Song:
def __init__(self, title, seconds):
self.title = title
self.seconds = seconds
first = Song("Morning Light", 215)
second = Song("Slow River", 302)
print(first > second)
Traceback (most recent call last):
File "main.py", line 9, in <module>
print(first > second)
^^^^^^^^^^^^^^
TypeError: '>' not supported between instances of 'Song' and 'Song'When you see this error, decide which attribute you meant to compare, and compare that.
Objects in a dictionary
Objects can be the values of a dictionary too. Here each song has a code, as on a jukebox:
class Song:
def __init__(self, title, seconds):
self.title = title
self.seconds = seconds
jukebox = {}
jukebox["A1"] = Song("Morning Light", 215)
jukebox["B7"] = Song("Slow River", 302)
code = "B7"
print("Now playing:", jukebox[code].title)
Now playing: Slow Riverjukebox[code] is a Song object, so .title can come right after it.