Что если тебе нужно будет заменить символ, которые заэскейпится при сериализации в джысон?
Что если искомая последовательность встретится не только в значениях, ноти в ключах?
Если это нужно для одноразовой задачи, где ты уверен, что вышеперечисленное точно не случится, то делай как хочешь. В противном случае вариант 2 не нормально работать не будет.
Ну конфиг, в некотором роде, тоже можно расценивать как входные данные, а там ни в чём нельзя быть уверенным на 100%. К слову, " – это тоже видимый ASCII символ.
def replace_arg(self, inplace, arg, args: Union[Dict, List, str]):
"""Replace template in arguments."""
if isinstance(args, list):
for index, value in enumerate(args):
if self.replace_arg(
inplace=inplace, arg=arg, args=value) is not None:
args[index] = arg
elif isinstance(args, dict):
for key, value in args.items():
if self.replace_arg(
inplace=inplace, arg=arg, args=value) is not None:
args[key] = arg
if args == inplace:
return arg
а где сама замена значения походящего ключа(ей) и на что ?
сейчас у тя всё для случая inplace==arg ( а это бывает только но не всегда при верхем вызове) чёт у тя рекурсия хромая
та замена только на первом уровне срабатывает в остальных случаях args достоверно не inplace - если это дерево - для графа конечно можеть и ...
короче как то сложно в вашей реализации - более того зачем копипастить можно же одним циклом что словарь что список обходить:
def replace_arg(self, inplace, arg, args: Union[Dict, List, str]):
if not isinstance(args, (list, dict, str)):
raise SystemExit("ой всё")
if not isinstance(args, (list, dict)):
pass # str ?!?
return # ???
if args != inplace:
return
def pairs(v):
return enumerate(v) if isinstance(v, list) else v.items()
for key, value in pairs(args):
if self.replace_arg(inplace, arg, args=value):
args[key] = arg
return arg
и в целом inplace и arg постоянны поэтому их по стеку можно и не гонять - а типо создать обьект с этими полями и уже этого анонима сделать сall по замене
поверхностно(?!) смотря на твой код очевидно что он хромает на большое количество конечностей сороконожки
ибо по факту эквивалентные преобразования делают очевидным что тот код который(на который я трансформацию привёл - по началу для удаления копипасты(один и тотже по сути перебор содержимого контейнера )) выше, и вращением веток стало очевидно, что либо эскиз кода либо он заведомо не универсален
т.е если код такого качество
то второй вариант - с заменой регуляркой в джсон-строке - получает преимущество но всё равно не побеждает
так то 1 вариант (рекурсивная замена по условию) предпочтительней
но вот код изначальный Ваш - он какой то радостный и божественный
Смотрел сообщения твоей первой инкарнации и сильно удивился, что они на русском. Более того, идеи все связанные, излагались в виде полных предложений, был даже сарказм. Что случилось дальше? Как так случилось, что ты перешёл с русского на китайско-русский переводчик?
def dickt_replace(d, s, r):
if isinstance(d, dict):
return {k: r if k == s else dickt_replace(v, s, r) for k, v in d.items()}
elif isinstance(d, list):
return [dickt_replace(item, s, r) for item in d]
else:
return d
наврядли те доли секунды важны для write-only скрипта. творец вместо решения глобальных задач распыляется на мелочи. индус бы уже портянку родил, получил за много строчек много денег, а в конце месяца премию за эффективность, а там через пару лет до CEO бы поднялся
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 в функцию, которая будет принимать ключ и новое значение, или вообще словарь замен — дело хозяйское. Главное, сам обход дерева теперь каждый раз заново песать не надо будет.