Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 21, 2014 15:44:07

Non_Stop
Зарегистрирован: 2014-07-29
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Заменить значение в словаре

Есть словарь

d = {"name": {"first": "One","last": "Drone"},"job": "scout","recent": {},"additional": {"place": {"zone": "1","cell": "2"}}}
Если в значениях попадается {}, его нужно зменить на “”. При этом мы не знаем глубину словаря. Как это сделать? Уже часа 2 пробую написать цикл, не получается.

Офлайн

#2 Авг. 21, 2014 15:51:48

GreyZmeem
От: Киев
Зарегистрирован: 2013-12-03
Сообщения: 147
Репутация: +  34  -
Профиль   Отправить e-mail  

Заменить значение в словаре

Как-то так:

# -*- 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': ''}

Офлайн

#3 Авг. 21, 2014 16:34:06

Budulianin
От:
Зарегистрирован: 2011-10-18
Сообщения: 1218
Репутация: +  33  -
Профиль   Отправить e-mail  

Заменить значение в словаре

import re
eval(re.sub(r'{}', "''", str(d)))



Офлайн

#4 Авг. 21, 2014 17:50:21

Budulianin
От:
Зарегистрирован: 2011-10-18
Сообщения: 1218
Репутация: +  33  -
Профиль   Отправить e-mail  

Заменить значение в словаре

den4ik
“Если символы { } не образуют квантификатор, их специальное значение игнорируется.” ©

хе-хе, прежде чем писать, лучше подумать, ещё лучше проверить :)



Отредактировано Budulianin (Авг. 21, 2014 17:51:23)

Офлайн

#5 Авг. 21, 2014 18:38:42

den4ik
Зарегистрирован: 2014-07-20
Сообщения: 59
Репутация: +  4  -
Профиль   Отправить e-mail  

Заменить значение в словаре

Budulianin
den4ik“Если символы { } не образуют квантификатор, их специальное значение игнорируется.” ©хе-хе, прежде чем писать, лучше подумать, ещё лучше проверить
дадада, я забыл про это, каюсь! не бейте(
И вариант GreyZmeem быстее.

Отредактировано den4ik (Авг. 21, 2014 18:39:42)

Офлайн

#6 Авг. 21, 2014 19:05:29

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Заменить значение в словаре

Если ТС без разницы, попадётся ему словарь, или строка, то я за вариант Budulianin.

Офлайн

#7 Авг. 21, 2014 19:18:31

Budulianin
От:
Зарегистрирован: 2011-10-18
Сообщения: 1218
Репутация: +  33  -
Профиль   Отправить e-mail  

Заменить значение в словаре

Так, ради интереса:

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]



Офлайн

#8 Авг. 21, 2014 19:27:27

den4ik
Зарегистрирован: 2014-07-20
Сообщения: 59
Репутация: +  4  -
Профиль   Отправить e-mail  

Заменить значение в словаре

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

Отредактировано den4ik (Авг. 21, 2014 19:29:14)

Офлайн

#9 Авг. 21, 2014 19:33:57

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Заменить значение в словаре

my_data = {
    "name": {
        "first": "One",
        "last": "Drone",
    },
    "job": "scout",
    "recent": {},
    "additional": {
        "place": {
            "zone": "zone{8345}",
            "cell": "2",
            "test": {},
        },
    },
}

Офлайн

#10 Авг. 21, 2014 19:34:09

Budulianin
От:
Зарегистрирован: 2011-10-18
Сообщения: 1218
Репутация: +  33  -
Профиль   Отправить e-mail  

Заменить значение в словаре

den4ik
Если вынести компиляцию регулярки наружу
при такой записи - re.sub, компиляция происходит 1 раз.

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

den4ik
re.MULTILINE
У нас всего одна строка.



Отредактировано Budulianin (Авг. 21, 2014 19:38:57)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version