简体   繁体   中英

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.

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)

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM