python-3.x – Help Using List/Dictionary Understanding

Question:

Hi, I have the following module (didn't want to put all the code here) in Python >= 3.6. It is already functional in its current state, although it doesn't handle all possible errors. But I want to practice changing some things. I'm not a programming professional, I'm actually a biologist, lol. But I use Python a lot and mainly R in research. So I apologize if the code is not as efficient and clean as possible.

The module renames video files that have their absolute episode numbers (25) instead of the season default (S02E03). Basically, it uses the pymediainfo package to detect videos in a folder and then it uses the tvdb_api package to identify the series and import information about it. This information will be used in the process of changing the filename with absolute episode number to the Season/Episode pattern.

I've been trying to replace the for loops for creating initial lists with list comprehension. I got it for two of the lists ( season and episodes ), but the third one ( absoluteNumbers ) I tried in many ways and didn't succeed.

Basically I want to transform the following for loops into list or dict comprehension:

for key in show:
    for value in show[key]:
        absoluteNumbers.append(show[key][value]['absoluteNumber'])

Similar to the other two lists:

seasons = [key for key in show for value in show[key]]
episodes = [value for key in show for value in show[key]]

My initial attempt was:

[absNum for k in show for v in show[k] for absNum in show[k][v]['absoluteNumber']]

But the result is not what was expected, something like a list containing the sequence of absolute numbers of the episodes of the series. For example, if we had two 10-episode seasons the list would have numbers from 1 to 20. What I get is an error:

TypeError: 'int' object is not iterable

Any suggestion?

Answer:

Looking at the code from the tvdb_api module you are using, the Show and Season class are children of dict where the Show class values ​​are seasons (as seen in the Show.search() method code ) and the Season class values ​​are episodes ( seen in the Season.search() method code ).

That is, the following code iterates over all episodes from all seasons and print the episodes treating Show and Season as dictionaries:

from tvdb_api import Tvdb

api = Tvdb()
serie = api['friends']

for season in serie.values():
    for ep in season.values():
        print(ep)

Code running on Repl.it

The output would be something like:

<Episode 01x01 - 'The One Where Monica Gets A Roommate'>
<Episode 01x02 - 'The One With The Sonogram At The End'>
<Episode 01x03 - 'The One With The Thumb'>
<Episode 01x04 - 'The One With George Stephanopoulos'>
<Episode 01x05 - 'The One With The East German Laundry Detergent'>
<Episode 01x06 - 'The One With The Butt'>
...
...
...
<Episode 10x15 - 'The One Where Estelle Dies'>
<Episode 10x16 - "The One With Rachel's Going Away Party (a.k.a. The One Where Rachel Goes ToParis)">
<Episode 10x17 - 'The Last One (1)'>
<Episode 10x18 - 'The Last One (2)'>

To get just the absoluteNumber of each episode it would be enough to treat the episode as a dict and get the value using ep['absoluteNumber'] . Using list comprehension would look like:

from tvdb_api import Tvdb

api = Tvdb()
serie = api['friends']

absoluteNumbers = [episodio['absoluteNumber'] for season in serie.values() 
                                              for episodio in season.values()]

print(absoluteNumbers)
# [1, 2, 3, 4, ..., 234, None, None]

Code running on Repl.it


You need to remember that TVDB is a database populated by volunteers and a lot of data might not exist, like the None values ​​shown in the code above.

Anyway, I believe this explains how to create a list of absoluteNumbers from episodes using comprehension . Just remember that the Show , Season and Episode classes for some reason inherit from dict , so you can iterate over them using the dict.items() ,dict.keys() and dict.values()

Scroll to Top