Skip to content

Instantly share code, notes, and snippets.

@kssreeram
Created July 22, 2015 14:36
Show Gist options
  • Save kssreeram/2da8e849275dea8a89cb to your computer and use it in GitHub Desktop.
Save kssreeram/2da8e849275dea8a89cb to your computer and use it in GitHub Desktop.
Python version of Clojure's merge-with and deep-merge-with
import operator
import itertools
def merge_key_with(f, k, dicts) :
if all((k in d) for d in dicts) :
return f(*(d[k] for d in dicts))
else :
first = next(itertools.ifilter(lambda d : k in d, dicts))
return first[k]
def merge_with(f, *dicts) :
all_keys = set(itertools.chain(*(d.iterkeys() for d in dicts)))
return dict((k, merge_key_with(f, k, dicts)) for k in all_keys)
def deep_merge_with(f, *dicts) :
def merge(*items) :
if all((type(d) is dict) for d in items) :
return merge_with(merge, *items)
else :
return f(*items)
return merge(*dicts)
u = {"a": {"b": {"c":1, "d":{"x":1, "y":2}}, "e":3}, "f":4}
v = {"a": {"b": {"c":2, "d":{"z":9}, "z":3}, "e":100}}
print u
print v
print deep_merge_with(operator.add, u, v)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment