Найти - Пользователи
Полная версия: Заменить значение в словаре
Начало » Python для новичков » Заменить значение в словаре
1 2 3
Non_Stop
Есть словарь
d = {"name": {"first": "One","last": "Drone"},"job": "scout","recent": {},"additional": {"place": {"zone": "1","cell": "2"}}}
Если в значениях попадается {}, его нужно зменить на “”. При этом мы не знаем глубину словаря. Как это сделать? Уже часа 2 пробую написать цикл, не получается.
GreyZmeem
Как-то так:
# -*- coding: utf-8 -*-
my_data = {
    "name": {
        "first": "One",
        "last": "Drone",
    },
    "job": "scout",
    "recent": {},
    "additional": {
        "place": {
            "zone": "1",
            "cell": "2",
            "test": {},
        },
    },
}
def fix_my_dict(my_dict):
    for name, value in my_dict.items():
        if isinstance(value, dict) and not value:
            my_dict[name] = ""
        elif isinstance(value, dict):
            my_dict[name] = fix_my_dict(value)
    return my_dict
print fix_my_dict(my_data)
{'additional': {'place': {'cell': '2', 'test': '', 'zone': '1'}}, 'job': 'scout', 'name': {'last': 'Drone', 'first': 'One'}, 'recent': ''}
Budulianin
import re
eval(re.sub(r'{}', "''", str(d)))
Budulianin
den4ik
“Если символы { } не образуют квантификатор, их специальное значение игнорируется.” ©

хе-хе, прежде чем писать, лучше подумать, ещё лучше проверить :)
den4ik
Budulianin
den4ik“Если символы { } не образуют квантификатор, их специальное значение игнорируется.” ©хе-хе, прежде чем писать, лучше подумать, ещё лучше проверить
дадада, я забыл про это, каюсь! не бейте(
И вариант GreyZmeem быстее.
Shaman
Если ТС без разницы, попадётся ему словарь, или строка, то я за вариант Budulianin.
Budulianin
Так, ради интереса:
d - глубокий словарь
def he_simple_func(d):
    eval(re.sub(r'{}', "''", str(d))


def fix_my_dict(my_dict):
    for name, value in my_dict.items():
        if isinstance(value, dict) and not value:
            my_dict[name] = ""
        elif isinstance(value, dict):
            my_dict[name] = fix_my_dict(value)

print(Timer("he_simple_func(d)", setup="from __main__ import he_simple_func, d").repeat(number=10000))
print(Timer("fix_my_dict(d)", setup="from __main__ import fix_my_dict, d").repeat(number=10000))

[3.272205114364624, 3.2799010276794434, 3.3669309616088867]
[0.03215813636779785, 0.03038811683654785, 0.02970290184020996]
den4ik
Budulianin
Так, ради интереса….
Если вынести компиляцию регулярки наружу, и убрать не нужный eval, то все ок.

# -*- coding: utf-8 -*-
import timeit
import re
my_data = {
    "name": {
        "first": "One",
        "last": "Drone",
    },
    "job": "scout",
    "recent": {},
    "additional": {
        "place": {
            "zone": "1",
            "cell": "2",
            "test": {},
        },
    },
}
r = re.compile(r'{}', re.MULTILINE).sub
def he_simple_func(d):
    return r("''", str(d))
def fix_my_dict(my_dict):
    for name, value in my_dict.items():
        if isinstance(value, dict) and not value:
            my_dict[name] = ""
        elif isinstance(value, dict):
            my_dict[name] = fix_my_dict(value)
    return my_dict
print(timeit.timeit('fix_my_dict(my_data)', setup='from __main__ import fix_my_dict, my_data', number=100000))
print(timeit.timeit('he_simple_func(my_data)', setup='from __main__ import he_simple_func, my_data', number=100000))

0.924198865891
0.75671505928
Shaman
my_data = {
    "name": {
        "first": "One",
        "last": "Drone",
    },
    "job": "scout",
    "recent": {},
    "additional": {
        "place": {
            "zone": "zone{8345}",
            "cell": "2",
            "test": {},
        },
    },
}
Budulianin
den4ik
Если вынести компиляцию регулярки наружу
при такой записи - re.sub, компиляция происходит 1 раз.

den4ik
и убрать не нужный eval
Кто тебе сказал, что он не нужен? Зачем нам строка на выходе? Нам нужен словарь.

den4ik
re.MULTILINE
У нас всего одна строка.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB