Craig
Craig

Reputation: 583

Is there a more Pythonic way to iterate through dictionary keys looking for a value than this?

Here is an example dictionary, colors:

{
    "Red" : {
        "members" : {
            "153950039532134112" : {
                "rank" : 1,
                "score" : 43,
                "time" : 1530513303
            }
        },
        "rank" : 2,
        "score" : 43
    },
    "Blue" : {
        "members" : {
            "273493248051539968" : {
                "rank" : 1,
                "score" : 849,
                "time" : 1530514923
            },
            "277645262486011904" : {
                "rank" : 2,
                "score" : 312,
                "time" : 1530513964
            },
            "281784064714487810" : {
                "rank" : 3,
                "score" : 235,
                "time" : 1530514147
            }
        },
        "rank" : 1,
        "score" : 1396
    }
}

For the sake of this example, let's assume that there are many more color-named keys in this dictionary. Now, assume I am looking for a particular member ID.

for key, value in colors.items():
    if member_id in value['members']:
        return True

Is there a simpler, possibly one-line way to do this?

Upvotes: 3

Views: 266

Answers (4)

Selcuk
Selcuk

Reputation: 59184

Here is another one-liner that uses any coupled with a generator expression:

return any(member_id in color['members'] for color in colors.values())

Upvotes: 7

DoloMike
DoloMike

Reputation: 529

You could use a list comprehension which is just a concise way to do your for loop and conditional statement.

The list comprehension below will return a color value when the member_id is present. If you check that the returned list has at least one value, you know the member_id was present in at least one color dict. If you make two lines and assign the output you could also have the color dict handy, in case you need to modify or read any of its state.

any([color for color in colorDict if member_id in colorDict[color]['members']])

I would say this is more pythonic than the example in your question, but sometimes list comprehensions can be unclear when there is more complexity involved. For example, if you needed two loops and two conditions then a list comprehension may not be the best choice. Overall they're an extremely useful tool, but it's up to you to decide when to use them.

Upvotes: 1

gilch
gilch

Reputation: 11651

next((k for k, v in colors.items() if member_id in v['members']), None)

Evaluates to the first color key with that member_id, like 'Blue' (or None if not found).

Generator expressions are lazy, so it will stop searching as soon as it finds a match.

Upvotes: 1

Ashish Acharya
Ashish Acharya

Reputation: 3399

Here's a one-line way of doing this:

member_id="273493248051539968"

[k for k, v in colors.items() if member_id in v['members']]

Output:

['Blue']

Upvotes: 1

Related Questions