python: what is best way to check multiple keys exists in a dictionary?

You can use set intersections:

if not d.viewkeys() & {'amount', 'name'}:
    raise ValueError

In Python 3, that'd be:

if not d.keys() & {'amount', 'name'}:
    raise ValueError

because .keys() returns a dict view by default. Dictionary view objects such as returned by .viewkeys() (and .keys() in Python 3) act as sets and intersection testing is very efficient.

Demo in Python 2.7:

>>> d = {
...   'name': 'name',
...   'date': 'date',
...   'amount': 'amount',
... }
>>> not d.viewkeys() & {'amount', 'name'}
False
>>> del d['name']
>>> not d.viewkeys() & {'amount', 'name'}
False
>>> del d['amount']
>>> not d.viewkeys() & {'amount', 'name'}
True

Note that this tests True only if both keys are missing. If you need your test to pass if either is missing, use:

if not d.viewkeys() >= {'amount', 'name'}:
    raise ValueError

which is False only if both keys are present:

>>> d = {
...   'name': 'name',
...   'date': 'date',
...   'amount': 'amount',
... }
>>> not d.viewkeys() >= {'amount', 'name'}
False
>>> del d['amount']
>>> not d.viewkeys() >= {'amount', 'name'})
True

For a strict comparison (allowing only the two keys, no more, no less), in Python 2, compare the dictionary view against a set:

if d.viewkeys() != {'amount', 'name'}:
    raise ValueError

(So in Python 3 that would be if d.keys() != {'amount', 'name'}).


You also could use set as:

>>> d = {
  'name': 'name',
  'date': 'date',
  'amount': 'amount',
}
>>> test = set(['name','date'])
>>> test.issubset(set(d.keys()))
True

if all(k not in d for k in ('name', 'amount')):
    raise ValueError

or

if all(k in d for k in ('name', 'amount')):
    # do stuff