История изменений
Исправление Nervous, (текущая версия) :
Можно слегка обобщить это всё*:
def identity (x):
return x
def partial (f, *args):
return lambda *more: f(*args, *more)
def walk (inner, outer, tree):
if isinstance(tree, dict):
return dict(map(lambda entry: [inner(entry[0]), inner(entry[1])], tree.items()))
elif isinstance(tree, list):
return outer(list(map(inner, tree)))
else:
return outer(tree)
def prewalk (f, tree):
return walk(partial(prewalk, f), identity, f(tree))
def postwalk (f, tree):
return walk(partial(postwalk, f), f, tree)
def foo_bar_to_baz (value):
if isinstance(value, dict) and "foo" in value and value["foo"] == "bar":
value["foo"] = "baz"
return value
d = {'spam': [{'foo': 'bar'}]}
print(d)
print(prewalk(foo_bar_to_baz, d))
d = {'spam': [{'foo': 'bar'}]}
d = {'spam': [{'foo': 'baz'}]}
Можно обернуть walk
/prewalk
/postwalk
в функцию, которая будет принимать ключ и новое значение, или вообще словарь замен — дело хозяйское. Главное, сам обход дерева теперь каждый раз заново песать не надо будет.
*содрано с https://github.com/clojure/clojure/blob/master/src/clj/clojure/walk.clj
Исправление Nervous, :
Можно слегка обобщить это всё*:
def identity (x):
return x
def partial (f, *args):
return lambda *more: f(*args, *more)
def walk (inner, outer, tree):
if isinstance(tree, dict):
return dict(map(lambda entry: [inner(entry[0]), inner(entry[1])], tree.items()))
elif isinstance(tree, list):
return outer(list(map(inner, tree)))
else:
return outer(tree)
def prewalk (f, tree):
return walk(partial(prewalk, f), identity, f(tree))
def postwalk (f, tree):
return walk(partial(postwalk, f), f, tree)
def foo_bar_to_baz (value):
if isinstance(value, dict) and "foo" in value and value["foo"] == "bar":
value["foo"] = "baz"
return value
d = {'spam': [{'foo': 'bar'}]}
print(d)
print(prewalk(foo_bar_to_baz, d))
d = {'spam': [{'foo': 'bar'}]}
d = {'spam': [{'foo': 'baz'}]}
Можно обернуть walk
/prewalk
/postwalk
в функцию, которая будет принимать ключ и новое значение, или вообще словарь замен — дело хозяйское. Главное, сам обход дерева теперь каждый раз заново песать не надо будет.
* содрано с https://github.com/clojure/clojure/blob/master/src/clj/clojure/walk.clj
Исходная версия Nervous, :
Можно слегка обобщить это всё*:
def identity (x):
return x
def partial (f, *args):
return lambda *more: f(*args, *more)
def walk (inner, outer, tree):
if isinstance(tree, dict):
return dict(map(lambda entry: [inner(entry[0]), inner(entry[1])], tree.items()))
elif isinstance(tree, list):
return outer(list(map(inner, tree)))
else:
return outer(tree)
def prewalk (f, tree):
return walk(partial(prewalk, f), identity, f(tree))
def postwalk (f, tree):
return walk(partial(postwalk, f), f, tree)
def foo_bar_to_baz (value):
if isinstance(value, dict) and "foo" in value and value["foo"] == "bar":
value["foo"] = "baz"
return value
d = {'spam': [{'foo': 'bar'}]}
print(prewalk(foo_bar_to_baz, d))
d = {'spam': [{'foo': 'bar'}]}
d = {'spam': [{'foo': 'baz'}]}
Можно обернуть walk
/prewalk
/postwalk
в функцию, которая будет принимать ключ и новое значение, или вообще словарь замен — дело хозяйское. Главное, сам обход дерева теперь каждый раз заново песать не надо будет.
* содрано с https://github.com/clojure/clojure/blob/master/src/clj/clojure/walk.clj