user2993021
user2993021

Reputation: 87

How to check for multiple keys in a dictionary if they are set to None?

I have the following which works but I'd like to see a more cleaner or pythonic way to do this.

if options_dict['cids'] is not None and options_dict['mergekeys'] is not None:
   # do something

The above will resolve to true if the keys 'cids' and 'mergekeys' exist. Is there a better way to do the above? Additionally, how can I also check the following at the same time.

if options_dict['cids'] is None and options_dict['mergekeys'] is None:
   # do something

It would be awesome if I could combine both of the above in the same if statement in a elegant way.

Upvotes: 2

Views: 1567

Answers (4)

Veedrac
Veedrac

Reputation: 60207

Truly the best way for the second in isolation is:

if options_dict['cids'] is options_dict['mergekeys'] is None:

Although personally for dispatch I would do:

# give meaningful name
flags = (options_dict['cids'] is None, options_dict['mergekeys'] is None)

if all(flags):
    ...

if not any(flags):
    ...

else:
    ...

Upvotes: 0

pillmuncher
pillmuncher

Reputation: 10162

Here's what I'd probably do:

>>> from operator import itemgetter
>>> my_dict = {"hey": 1, "ho": 2, "let's": 3, "go": None}
>>> my_keys = "hey", "ho"
>>> my_values = itemgetter(*my_keys)
>>> my_values(my_dict)
(1, 2)
>>> None not in my_values(my_dict)
True
>>> my_keys = "let's", "go"
>>> my_values = itemgetter(*my_keys)
>>> my_values(my_dict)
(3, None)
>>> None not in my_values(my_dict)
False

Upvotes: 0

user2555451
user2555451

Reputation:

You could always use all and a generator expression:

if all(options_dict[x] is not None for x in ('cids', 'mergekeys')):

Although I personally think that your current solution is better. It is clear and more efficient than this one.

If the length of yours is the problem, then you can simply break it up over multiple lines:

if options_dict['cids'] is not None and 
    options_dict['mergekeys'] is not None:

Or, make a shorter name for the dictionary:

dct = options_dict
if dct['cids'] is not None and dct['mergekeys'] is not None:

The all and generator expression solution should only be used for checking more keys than just two or three.

Upvotes: 3

Use a list comprehension to make a list of bools telling if the corresponding option was None:

nones = [ options_dict[i] is None for i in [ 'cids', 'mergekeys' ] ]

Then you can use the any and all predicates to test if any or all are None:

if not any(nones):
    # not a single one was none

elif all(nones):
    # all were nones

Upvotes: 1

Related Questions