How to Check If One Dictionary Is a Subset of Another Larger Dictionary

How to check if one dictionary is a subset of another larger dictionary?

Convert to item pairs and check for containment.

all(item in superset.items() for item in subset.items())

Optimization is left as an exercise for the reader.

Test if dict contained in dict

You can use a dictionary view:

# Python 2
if first.viewitems() <= second.viewitems():
# true only if `first` is a subset of `second`

# Python 3
if first.items() <= second.items():
# true only if `first` is a subset of `second`

Dictionary views are the standard in Python 3, in Python 2 you need to prefix the standard methods with view. They act like sets, and <= tests if one of those is a subset of (or is equal to) another.

Demo in Python 3:

>>> first  = {"one":"un", "two":"deux", "three":"trois"}
>>> second = {"one":"un", "two":"deux", "three":"trois", "foo":"bar"}
>>> first.items() <= second.items()
True
>>> first['four'] = 'quatre'
>>> first.items() <= second.items()
False

This works for non-hashable values too, as the keys make the key-value pairs unique already. The documentation is a little confusing on this point, but even with mutable values (say, lists) this works:

>>> first_mutable = {'one': ['un', 'een', 'einz'], 'two': ['deux', 'twee', 'zwei']}
>>> second_mutable = {'one': ['un', 'een', 'einz'], 'two': ['deux', 'twee', 'zwei'], 'three': ['trois', 'drie', 'drei']}
>>> first_mutable.items() <= second_mutable.items()
True
>>> first_mutable['one'].append('ichi')
>>> first_mutable.items() <= second_mutable.items()
False

You could also use the all() function with a generator expression; use object() as a sentinel to detect missing values concisely:

sentinel = object()
if all(first[key] == second.get(key, sentinel) for key in first):
# true only if `first` is a subset of `second`

but this isn't as readable and expressive as using dictionary views.

Recursive function to check dictionary is a subset of another dictionary

Your code logic is upside down. Notice how you take each element in the superset and continue if they are not in the subset. What you want to do is take each element in the subset and check that they are in the superset.

Here is a fixed version of you code.

def is_subset(superset, subset):
for key, value in subset.items():
if key not in superset:
return False

if isinstance(value, dict):
if not is_subset(superset[key], value):
return False

elif isinstance(value, str):
if value not in superset[key]:
return False

elif isinstance(value, list):
if not set(value) <= set(superset[key]):
return False
elif isinstance(value, set):
if not value <= superset[key]:
return False

else:
if not value == superset[key]:
return False

return True

Here are some example of the function giving the correct result.

superset = {'question': 'mcve', 'metadata': {}}
subset = {'question': 'mcve', 'metadata': {'author': 'BPL'}}

is_subset(superset, subset) # False

superset = {'question': 'mcve', 'metadata': {'foo': {'bar': 'baz'}}}
subset = {'metadata': {'foo': {}}}

is_subset(superset, subset) # True

superset = {'question': 'mcve', 'metadata': {'foo': 'bar'}}
subset = {'question': 'mcve', 'metadata': {}, 'baz': 'spam'}

is_subset(superset, subset) # False

Python: How can one verify that dict1 is only a subset of dict2? Values are all int and within scope

You could try the collections Counter - it's very efficient and clear. Note - it's a new feature available in Python 3.10.

It's dict subclass for counting hashable objects


from collections import Counter
cd1 = Counter(test_dict)
cd2 = Counter(test_dict2)
print(cd1 <= cd2)
# True
#
# another example:
cd3 = Counter({'a': 2, 'b': 2, 'c': 3})
print(cd3 <= cd2)
#False
print(cd2 <= cd3)
#True

Comparing two dictionaries and checking how many (key, value) pairs are equal

If you want to know how many values match in both the dictionaries, you should have said that :)

Maybe something like this:

shared_items = {k: x[k] for k in x if k in y and x[k] == y[k]}
print(len(shared_items))

Check if dictionary contain another dictionary

You can do:

dict1 = {"Name": "Bob", "Surname": "Smith", "Age": 30}

dict2 = {"Name": "Bob", "Surname": "Smith"}

print(all(dict1[k] == v for k, v in dict2.items()))

How to compare one dictionary to part of another dictionary?

To get the dictionaries to compare for equality, you need to get the name key and value out of the row dictionary. If the 'name' key and value are still in the row dictionary, it will never == the seq_master_list dictionary.

found = False
for row in dna:
name = row.pop('name') # remove this from the 'row' dict and save the name
if row == seq_master_list:
found = True
print(name)
break

if not found:
print('no match')


Related Topics



Leave a reply



Submit