David542
David542

Reputation: 110562

How to reduce repetitive code in if/elif statement

What would be a better way to do the following pattern?

for platform_id in previous_platform_ids:
    if self.series.get(platform_id):
        del self.series[platform_id]
    elif self.seasons.get(platform_id):
        del self.seasons[platform_id]
    elif self.episodes.get(platform_id):
        del self.episodes[platform_id]
    elif self.movies.get(platform_id):
        del self.movies[platform_id]
    elif self.bundles.get(platform_id):
        del self.bundles[platform_id]

Basically, I want to iterate through a bunch of ids and remove that id from the list that contains it.

Upvotes: 1

Views: 89

Answers (3)

David542
David542

Reputation: 110562

One way to do it is to iterate through each content_type and use the getattr method to check if it's there:

content_types = ['series', 'seasons', 'episodes', 'movies', 'bundles']
for url in previous_urls:
    for content_type in content_types:
        if getattr(self, content_type).get(url):
            del getattr(self, content_type)[url]
            break

Upvotes: 2

Reut Sharabani
Reut Sharabani

Reputation: 31349

What about:

dicts = [self.series, ..., ]
remove_id_func = lambda _id: map(lambda dct: dct.pop(_id, None), dicts)

Somehow keeping them in a list seems nicer, and now use it like this:

remove_id_func(some_id)

An even nicer thing is to keep them in a mapping:

dicts = {
    "series": self.series,
    "movies": self.movies,
    ...
}

And the remove function now becomes:

remove_id_func = lambda _id: map(lambda kv: kv[1].pop(_id, None), dicts.items())

You can use class methods with simple loops which is probably better than these one-liners which are unmaintainable.

Note that these operations remove the element from all lists, which is what you probably want.

Upvotes: 2

Joran Beasley
Joran Beasley

Reputation: 114098

self.series.pop(platform_id,None)
self.seasons.pop(platform_id,None)
self.episodes.pop(platform_id,None)
self.movies.pop(platform_id,None)
self.bundles.pop(platform_id,None)

seems like it would do the same thing (or actually not quite this will delete it from all dictionaries it(the key) is present in not just, the first one it finds, your code will only delete the first instance it finds ... not sure if that is intentional)

of coarse you could do something like

for content_type in content_types:
    getattr(self, content_type).pop(platform_id,None)

if you only wanted to delete the first one you found you could do

 content_dicts = [self.series,self.seasons,self.episodes,self.movies,self.bundles]
 next(x.pop(platform_id,None) for x in content_dicts if platform_id in x)

Upvotes: 2

Related Questions