Как обновить значение уникального ключа во вложенном словаре?

Endogen спросил: 31 июля 2018 в 09:35 в: python-3.x

Предположим, что у нас есть этот dict:

{
  "app_url": "",
  "models": [
    {
      "perms": {
        "add": true,
        "change": true,
        "delete": true
      },
      "add_url": "/admin/cms/news/add/",
      "admin_url": "/admin/cms/news/",
      "name1": ""
    }
  ],
  "has_module_perms": true,
  "name2": "u\u0027CMS\u0027"
}

Как установить новое значение для ключа add_url, если требование должен предоставить только ключ и значение?

Поэтому я не хочу делать что-то вроде data["models"]["add_url"] = value, но вместо этого хочу передать только "add_url" и новое значение для функции.

В моем случае каждый ключ в dict является уникальным str, так что не может случиться, что появляется ключ более одного раза.

1 ответ

Есть решение
Julian Camilleri ответил: 31 июля 2018 в 10:14

Вы можете использовать рекурсивную функцию, чтобы найти поле и обновить значение.

your_dict = {
  "app_url": "",
  "models": [
    {
      "perms": {
        "add": True,
        "change": True,
        "delete": True
      },
      "add_url": "/admin/cms/news/add/",
      "admin_url": "/admin/cms/news/",
      "name1": ""
    }
  ],
  "has_module_perms": True,
  "name2": "u\u0027CMS\u0027"
}def recursive_update(haystack, needle, value):
  if isinstance(haystack, dict):
    for key, value_dict in haystack.items():
      if needle == key:
        haystack[key] = value
      elif isinstance(value_dict, list) or isinstance(value_dict, dict):
          recursive_update(value_dict, needle, value)
  elif isinstance(haystack, list):
    for value_list in haystack:
      if isinstance(value_list, dict):
        recursive_update(value_list, needle, value)  return haystack

Использование:

recursive_update(your_dict, 'add_url', 'http://www.google.com')

Примечание. Я не рекомендую вам использовать неявный подход к программированию.

Вышеприведенное не проверено полностью, поэтому обязательно проверьте его; это скорее пример того, как рекурсия может работать для достижения вашей цели.

bruno desthuilliers ответил: 31 июля 2018 в 10:27
намек; не делайте этого. Это лучший способ получить поврежденные данные без предупреждения. Python Zen # 11: "перед лицом двусмысленности откажитесь от соблазна гадать".
Endogen ответил: 31 июля 2018 в 10:38
Функция не угадывает. Я могу гарантировать, что каждый ключ уникален. Будем использовать это :-)
Julian Camilleri ответил: 05 августа 2018 в 11:10
@brunodesthuilliers Я понимаю вашу точку зрения; поскольку я был во многих трудных ситуациях с неопределенностью и неявным предположением, что вам понадобится в будущем; но мне любопытно на самом деле; Можете ли вы предоставить мне альтернативу?
Endogen ответил: 31 июля 2018 в 10:44
@belthazorNv Это именно то, что я хотел, спасибо! Посмотрим на это, чтобы убедиться, что он работает в каждом возможном случае.
Julian Camilleri ответил: 31 июля 2018 в 11:58
Просто чтобы прояснить, я не люблю делать что-то столь же двусмысленное и неявное, как это, хотя да, есть случаи, когда вы загнаны в угол и должны это делать. - Я рад, что это помогло.