Both sets have one element: One has the key value tuple "name":"Girls" and the other has the single element composed of a key value tuple "show": {"name": "Girls"} and when two sets both have one element, those elements must be equal for the sets to be considered subsets of eachother.
Both can be nested. A list can contain another list. A dictionary can contain another dictionary. A dictionary can also contain a list, and vice versa.
The simplest technique to check if two or multiple dictionaries are equal is by using the == operator in Python. You can create the dictionaries with any of the methods defined in Python and then compare them using the == operator. It will return True the dictionaries are equals and False if not.
In Python 3, you can use dict.items()
to get a set-like view of the dict items. You can then use the <=
operator to test if one view is a "subset" of the other:
d1.items() <= d2.items()
In Python 2.7, use the dict.viewitems()
to do the same:
d1.viewitems() <= d2.viewitems()
In Python 2.6 and below you will need a different solution, such as using all()
:
all(key in d2 and d2[key] == d1[key] for key in d1)
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.
Note for people that need this for unit testing: there's also an assertDictContainsSubset()
method in Python's TestCase
class.
http://docs.python.org/2/library/unittest.html?highlight=assertdictcontainssubset#unittest.TestCase.assertDictContainsSubset
It's however deprecated in 3.2, not sure why, maybe there's a replacement for it.
For completeness, you can also do this:
def is_subdict(small, big):
return dict(big, **small) == big
However, I make no claims whatsoever concerning speed (or lack thereof) or readability (or lack thereof).
Update: As pointed out by Boris' comment, this trick does not work if your small dict has non-string keys and you're using Python >= 3 (or in other words: in the face of arbitrarily typed keys, it only works in legacy Python 2.x).
If you are using Python 3.9 or newer, though, you can make it work both with non-string typed keys as well as get an even neater syntax.
Provided your code already has both dictionaries as variables, it's very concise to check for this inline:
if big | small == big:
# do something
Otherwise, or if you prefer a reusable function as above, you can use this:
def is_subdict(small, big):
return big | small == big
The working principle is the same as the first function, only this time around making use of the union operator that was extended to support dicts.
for keys and values check use:
set(d1.items()).issubset(set(d2.items()))
if you need to check only keys:
set(d1).issubset(set(d2))
>>> d1 = {'a':'2', 'b':'3'}
>>> d2 = {'a':'2', 'b':'3','c':'4'}
>>> all((k in d2 and d2[k]==v) for k,v in d1.iteritems())
True
context:
>>> d1 = {'a':'2', 'b':'3'}
>>> d2 = {'a':'2', 'b':'3','c':'4'}
>>> list(d1.iteritems())
[('a', '2'), ('b', '3')]
>>> [(k,v) for k,v in d1.iteritems()]
[('a', '2'), ('b', '3')]
>>> k,v = ('a','2')
>>> k
'a'
>>> v
'2'
>>> k in d2
True
>>> d2[k]
'2'
>>> k in d2 and d2[k]==v
True
>>> [(k in d2 and d2[k]==v) for k,v in d1.iteritems()]
[True, True]
>>> ((k in d2 and d2[k]==v) for k,v in d1.iteritems())
<generator object <genexpr> at 0x02A9D2B0>
>>> ((k in d2 and d2[k]==v) for k,v in d1.iteritems()).next()
True
>>> all((k in d2 and d2[k]==v) for k,v in d1.iteritems())
True
>>>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With