Задать вопрос
fandorin_official
@fandorin_official
Герой серии исторических детективов.

Как передать ключ «сложного» словаря в качестве аргумента функции?

К примеру у меня есть вот такой словарь:
exampe = {'Building': {
    'Flat': {
        'Flat_1': {
            'App_1': 3, 
            'App_2': 5}, 
        'Flat_2': {
            'App_3': 1, 
            'App_4': 3
        }
    }
}
}

Я считываю json, записываю его в словарь.
with open("log.json", "r") as json_data:
        guests = json.load(json_data)
        json_data.close()

Получить значение 'App_4' я могу следующим образом:
count = guests[Building][Flat][Flat_2][App_4]
Как я могу передать в качестве аргумента функции "весь" ключ ([Building][Flat][Flat_2][App_4]) для того чтобы изменить либо считать нужно мне значение?
  • Вопрос задан
  • 543 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
NeiroNx
@NeiroNx
Программист
Думаю автор хотел обращаться к структуре данных из вложенных словарей используя одну переменную.

В принципе это не сложно реализовать 2 функциями:
def GetVal(array,key):
	result = array
	for k in key.split("."): result = result[k]
	return result
def SetVal(array,key,val):
	def merge(a,b):
		for k,v in b.items():
			if k in a.keys() and isinstance(a[k],dict):
				merge(a[k],v)
			else:
				a[k] = v
	result = val
	for k in key.split(".")[::-1]: result = {k:result}
	merge(array,result)
	return array

Первая функция рекурсивно присваивает значения, пока не закончатся ключи
Вторая функция строит структуру массива и выполняет рекурсивное слияние и присвоение элемента.

Протестируем работу:
>>> exampe = {'Building': {
    'Flat': {
        'Flat_1': {
            'App_1': 3, 
            'App_2': 5}, 
        'Flat_2': {
            'App_3': 1, 
            'App_4': 3
        }
    }
}
}
>>> GetVal(exampe,"Building.Flat.Flat_2.App_4")
3
>>> SetVal(exampe,"Building.Flat.Flat_2.App_4",7)
{'Building': {'Flat': {'Flat_1': {'App_1': 3, 'App_2': 5}, 'Flat_2': {'App_3': 1, 'App_4': 7}}}}
>>> GetVal(exampe,"Building.Flat.Flat_2.App_4")
7
>>>
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
sergey-gornostaev
@sergey-gornostaev Куратор тега Python
Седой и строгий
from functools import reduce, wraps


def silenced(*exceptions, typed=False):
    def decorator(f):
        @wraps(f)
        def wrapper(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            except exceptions as exc:
                if typed:
                    return exc.__class__
                return None
        return wrapper
    return decorator


@silenced(IndexError, KeyError)
def item_getter(container, key):
    if container is not None:
        return container[key]


exampe = {
  'Building': {
    'Flat': {
      'Flat_1': {
        'App_1': 3, 
        'App_2': 5
      }, 
      'Flat_2': {
        'App_3': 1, 
        'App_4': 3
      }
    }
  }
}

path = ['Building', 'Flat', 'Flat_2', 'App_4']
value = reduce(item_getter, path, example)
print(value)
Ответ написан
Комментировать
Guest007
@Guest007
Django, Python, Linux и всё такое...
Получить значение - просто
def a(b):
    print(b)

a(guests[Building][Flat][Flat_2][App_4])


А изменять лучше не внутри функции:
def a(b, c):
    return b += c

guests[Building][Flat][Flat_2][App_4] = a(guests[Building][Flat][Flat_2][App_4], 4)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы