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
Split Views.Py in Several Files
How to Get Char from String by Index
How to Find the First Key in a Dictionary
Adding Borders to an Image Using Python
Sort Multidimensional Array Based on 2Nd Element of the Subarray
Writing to a File in a for Loop Only Writes the Last Value
Filtering a List Based on a List of Booleans
Thread Local Storage in Python
Access Class Variable from Instance
Check If a Given Key Already Exists in a Dictionary and Increment It
Any Gotchas Using Unicode_Literals in Python 2.6
Real World Example About How to Use Property Feature in Python
How to Get Exception Message in Python Properly
Fastest Way to Search a List in Python
Loop Over a List Containing Path to Sound Files