Help Using List Comprehension/Dictionary

Asked

Viewed 161 times

7

Hello, I have the following module (did not want to put all the code here) in Python >= 3.6. It is already functional in the current state, although it does not handle all possible errors. But I want to, to practice, change some things. I’m not a programming professional, I’m actually a biologist, rsrs. But I use a lot of Python 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 are with their absolute number of episodes (25) instead of the standard per season (S02E03). Basically, he uses the package pymediainfo to detect videos in a folder and then uses the package tvdb_api to identify the series and import information about it. This information will be used in the process of changing the file name with absolute episode number to the default Season/Episode.

I’ve been trying to replace the links for creating the initial lists by list comprehension. I got for two of the lists (Season and episodes), but the third (absoluteNumbers) I have tried many ways and failed.

Basically I want to turn the following links for into list or Dict comprehension:

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

Similar to the one done with 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 series' episodes. For example, if we had two seasons of 10 episode the list would have the numbers from 1 to 20. What I get is an error:

TypeError: 'int' object is not iterable

Any suggestions?

  • Have you tried debugging and seeing what’s coming out, like printing out every value of that for? because this error occurs when you try to integer a whole type, make a for with the numeral 1, then any language is half lost, because you can only know if it is a list,Arry dics . in this link can help you understand better.

  • So, I did a debug and error is this same, in my version it tries to iterate a type None, the problem is that I can not get around it, the logic of this list comprehension is escaping me beautiful. 'NoneType' object is not iterable

  • can you give me an example of filename? See if I test here and give you a better answer

  • Dude, I went around here and put the file name of 'Leverage' a series. I see that there are some absolutenumber that this as None. What you can do to get around this is an accountant, since he goes through all the seasons and every time he passes is a new episode there will add up every step.

2 answers

3


Analyzing the module code tvdb_api that you’re using, the class Show and Season are the daughters of dict where the class values Show are seasons (as seen in method code Show.search()) and the values of the class Season are episodic (seen in method code Season.search()).

That is, the following code iterates over all episodes of all seasons and gives a print of the episodes dealing 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 way out 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 catch only the absoluteNumber of each episode it would be enough to treat the episode as a dict and take the value using ep['absoluteNumber']. Using comprehensilist on would be:

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 filled by volunteers and many data may not exist, as the values None shown in the code above.

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

0

From what I saw the tvbd’s own API does not have the information from absoluteNumber for every episode, so it returns None. A solution would be to "create" your own absoluteNumber, as follows in the code tree below.

absoluteNumber = 0
for key in show:
    for value in show[key]:
        absoluteNumber+=1
        absoluteNumbers.append(absoluteNumber)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.