Home > Software design >  Can I use kwargs inside list comprehension?
Can I use kwargs inside list comprehension?

Time:09-05

I was playing with some older functions (trying to improve older code) and then I start to wonder if it's possible to use kwargs directly inside a list comprehension.

For example, I have this dataset:

data = {"channels": [
    {"channel_id": 1, "group_id": 1, "description": "First", "default_msg": "Hi!", "status": True},
    {"channel_id": 2, "group_id": 1, "description": "Second", "default_msg": "Hi!", "status": True},
    {"channel_id": 3, "group_id": 1, "description": "Third", "default_msg": "Hi!", "status": False},
    {"channel_id": 4, "group_id": 2, "description": "Fourth", "default_msg": "Hi!", "status": True},
    {"channel_id": 5, "group_id": 2, "description": "Fifth", "default_msg": "Hi!", "status": False},
]}

I easily can do something like:

def get_by_groups(group):
    return [c for c in data["channels"] if c["group_id"] == group]

But the idea of receiving the query parameters by kwargs, and using it directly inside the list comprehension just looks magical. I tried to look up examples but did not have any success.

Yes, I could unpack all kwargs and do a loop for each argument, but doesn't seem that nice, like something like:

def get_channels(**kwargs):
    return [c for c in data["channels"] if c[kwargs.keys()] == kwargs.values()]

EDIT

Just to clarify. I don't think there is anything wrong with:

def get_channels(**kwargs) -> list:
        lst_groups = data["channels"]
        for key, value in kwargs.items():
            lst_groups = [c for c in lst_groups if c[key] == value]
        return lst_groups

It's just curiosity...

CodePudding user response:

You could do:

def get_channels(**kwargs):
    return [c for c in data["channels"] if all(c[k]==v for k,v in kwargs.items())]

This behavior matches your edit code, where every condition has to be satisfied. A different requirement might make use of any().

I would be careful though, because it is very easy to introduce bugs when the field names are being passed around as kwargs. They would have to exactly match what is inside data['channels'] otherwise you'll get KeyError.

And if this is not just an internal method, the caller now needs to know the exact keys used in your data structure and it would be harder for you to change things without breaking dependent code in the future.

  • Related