Удалить ключи, но сохранить значения из словаря

#python

#python

Вопрос:

Допустим, у меня есть этот словарь:

 {
  "id": "132-sd-sa-23-a-1",
  "data": {
    "lastUpdated": { "S": "2020-07-22T21:39:20Z" },
    "profile": {
      "M": {
        "address": { "L": [] },
        "fakeField": { "S": "someValue" },
        "someKey": { "M": { "firstName": { "S": "Test" } } }
      }
    },
    "groups": {
      "L": [{ "S": "hello world!" }]
    }
  }
}
  

Как я могу удалить ключи «M», «S», «L» и т.д. Из словаря, но сохранить значения. Таким образом, это превратилось бы в это:

 {
  "id": "132-sd-sa-23-a-1",
  "data": {
    "lastUpdated": "2020-07-22T21:39:20Z",
    "profile": {
      "address": [],
      "fakeField": "someValue",
      "someKey": { "firstName": "Test" }
    },
    "groups": ["hello world!"]
  }
}
  

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

Комментарии:

1. d['data']['profile'] = d['data']['profile']['M'] ? И так далее.

2. Не удаляйте материал, просто создайте новый словарь со сглаженными ключами / значениями.

3. Спасибо! Это показало мне другие способы сделать это и то, что изменение исходного списка может оказаться не очень хорошей идеей.

Ответ №1:

Звучит как задание для рекурсии:

 def unsml(obj):
    if isinstance(obj, dict):
        if len(obj) == 1:
            (key, value), *_ = obj.items()  # get the only key and value
            if key in "SML":
                return unsml(value)
        return {
            key: unsml(value) if isinstance(value, dict) else value
            for key, value
            in obj.items()
        }
    elif isinstance(obj, list):
        return [unsml(value) for value in obj]
    return obj
  

Тогда просто сделайте new_dict = unsml(old_dict) .

Комментарии:

1. «un-«, как в remove, «sml», как в «S», «M», «L». Не стесняйтесь предлагать лучшее название.

2. вы можете использовать key, value = obj.popitem() , чтобы получить единственный ключ и значение, в противном случае отличный ответ!

3. @Amir Я мог бы, да, но тогда я бы изменил исходную структуру данных. Я знаю, что (key, value), *_ часть немного неясна, но мне нравится сохранять функции чистыми, если это возможно.

4. Большое вам спасибо! Это намного лучше, чем то, что я делал (манипулирование строками).