Skip to content

Instantly share code, notes, and snippets.

@rossmacarthur
Created August 8, 2018 11:40
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rossmacarthur/38fa948b175abb512e12c516cc3b936d to your computer and use it in GitHub Desktop.
Save rossmacarthur/38fa948b175abb512e12c516cc3b936d to your computer and use it in GitHub Desktop.
A Python dictionary type that allows set operations for nested dictionaries.
class DictSet(dict):
"""
A dictionary type that allows set operations for nested dictionaries.
"""
def __or__(self, other):
return self.union(other)
def __and__(self, other):
return self.intersection(other)
def __sub__(self, other):
return self.difference(other)
def union(self, other):
"""
Return the union of two dictionaries.
In the case of a conflict the right operand takes precedance.
"""
result = DictSet()
for key in (self.keys() | other.keys()):
if isinstance(self.get(key), dict) and isinstance(other.get(key), dict):
result[key] = DictSet(self[key]).union(other[key])
else:
result[key] = other.get(key, self.get(key))
return result
def intersection(self, other):
"""
Return the intersection of two dictionaries.
In the case of a conflict neither dictionary value is present.
"""
result = DictSet()
for key in (self.keys() & other.keys()):
if isinstance(self.get(key), dict) and isinstance(other.get(key), dict):
subresult = DictSet(self[key]).intersection(other[key])
if subresult:
result[key] = subresult
elif self.get(key) == other[key]:
result[key] = self[key]
return result
def difference(self, other):
"""
Return the difference of two dictionaries.
In the case of a conflict the left operand takes precedance.
"""
result = DictSet()
for key in (self.keys() | other.keys()):
if isinstance(self.get(key), dict) and isinstance(other.get(key), dict):
subresult = DictSet(self[key]).difference(other[key])
if subresult:
result[key] = subresult
elif self.get(key) != other.get(key):
result[key] = self.get(key, other.get(key))
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment