简体   繁体   English

用子字典中的一个替换父键值?

[英]Replace parent key value with one from sub-dictionary?

I have a dict as below:我有一个dict如下:

{'data': 'v1', 'data2': {'xyz': 'ABC' }}

I want to have a dict like:我想要一个像这样的dict

{'data': 'v1', 'data2': 'ABC'}

Basically I want to use the value of key of 'data2' to be assigned to 'data2' .基本上我想使用'data2'的键值分配给'data2'

This is a deeply nested recursive dictionary with multiple levels.这是一个深度嵌套的多层次递归字典。

Here's a pure python way to do this:这是执行此操作的纯python方法:

newdict={}
for k,v in data.items():
    if type(v) == str:
        newdict[k] = v
    else:
        newdict[k] = list(v.values())[0]

# {'data': 'v1', 'data2': 'ABC'}

You also can convert to a pandas dataframe and extract the information you want with it.您还可以转换为 Pandas 数据框并使用它提取您想要的信息。 Here's two examples:这里有两个例子:

import pandas as pd
q= pd.DataFrame({'data': 'v1', 'data2': 'ABC'}, index=[0])
w=pd.DataFrame({'data': 'v1', 'data2': {'xyz': 'ABC' }})
q.merge(w).to_dict(orient='records'
)                                                                                                                                                
#  [{'data': 'v1', 'data2': 'ABC'}]

or或者

w.to_dict(orient='records')                                                                                                                                                         
# [{'data': 'v1', 'data2': 'ABC'}]

You could use a function to un-nest specific key pairs of a dict .您可以使用函数来取消嵌套dict特定密钥对。 Though, this example will only work if the nested dict has a single key that you want to promote.但是,此示例仅在嵌套dict具有您要提升的单个键时才有效。

def unnest(root_dict, **key_map):
    """
    root_dict: This is the dict object to work with.
    **key_map: These are the key="nested_key" pairs to promote.
    """
    obj = root_dict.copy()
    for key, nested_key in key_map.items():
        obj[key] = obj[key][nested_key]
    return obj

Using this function with your example input:将此函数与您的示例输入一起使用:

>>> example_dict = {'data': 'v1', 'data2': {'xyz': 'ABC' }}
>>> unnest(example_dict, data2="xyz")
{'data': 'v1', 'data2': 'ABC'}

I was solving a similar problem with translating some JSON fields.我正在通过翻译一些 JSON 字段来解决类似的问题。

At the entrance I had a nested document with some keys that included a nested object with translations in different languages:在入口处,我有一个带有一些键的嵌套文档,其中包含一个带有不同语言翻译的嵌套对象:

json_data = {
      "title": {
        "uk": "title 1 uk",
        "ru": "title 2 uk",
        "en": "title 3 uk"
      },
      "items": [
        {
          "subcategory": {
            "uk": "subcategory 1 uk",
            "ru": "subcategory 1 ru",
            "en": "subcategory 1 en"
          },
          "items": [
            {
              "id": 1,
              "title": {
                "en": "title en 1",
                "ru": "title ru 1",
                "uk": "title uk 2"
              }
            },
            {
              "id": 2,
              "title": {
                "en": "title en 1.2",
                "ru": "title ru 1.2",
                "uk": "title uk 1.2"
              }
            }
          ]
        },
        {
          "subcategory": {
            "uk": "subcategory 1.2 uk",
            "ru": "subcategory 1.2 ru",
            "en": "subcategory 1.2 en"
          },
          "items": [
            {
              "id": 2,
              "title": {
                "en": "title en 2.2",
                "ru": "title ru 2.2",
                "uk": "title uk 2.2"
              }
            }
          ]
        }
      ]
    }

There is a recursive generator, accepts a document as input, and the name of the key that I am looking for, the value of which will be returned as value of the parent key.有一个递归生成器,接受一个文档作为输入,以及我正在寻找的键的名称,其值将作为父键的值返回。

def i18n_generator(json_input={}, language="en"):

    if isinstance(json_input, dict):
        for k, v in json_input.items():
            if isinstance(v, dict) and language in v:
                """
                    if value is a dict and contains the required field, 
                    set to the parent key value from nested object
                """
                json_input[k] = v.get(language, None)
                yield
            else:
                yield from i18n_generator(v, language)

    elif isinstance(json_input, list):
        # if the document contains a list of dictionaries
        for item in json_input:
            yield from i18n_generator(item, language)

# run generator
for _ in i18n_generator(json_data, language="uk"):
    pass

print(json_data)

output:输出:

{'title': 'title 1 uk', 'items': [{'subcategory': 'subcategory 1 uk', 'items': [{'id': 1, 'title': 'title uk 2'}, {'id': 2, 'title': 'title uk 1.2'}]}, {'subcategory': 'subcategory 1.2 uk', 'items': [{'id': 2, 'title': 'title uk 2.2'}]}]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM