简体   繁体   English

用列表中的相应内容替换嵌套字典中的元素

[英]Replace elements in a nested dict with the appropriate in a list

I have such following a dict and a list. 我有这样的命令和清单。

mylist= ['1H1.PyModule.md',
         '1H2.Class.md',
         '1H3.MetaObject.md',
         '2B1D0.Data.md',
         '2B1D1.Primitive.md',
         '2B1D2.Operator.md',
         '2B2D3.Container.md',
         '2B2S0.Function.md',
         '2B2S0.Statemment.md',
         '2B2S1.Controlled_Loop.md',
         '2B2S2.Conditions.md',
         '2B2S3.Except.md',
         ...
         ]
 mydict = {'Body': {'Data': ['1.primitive', '2.operator', '3.container'],
   'Statement': ['0.function', '1.controlled_loop', '2.condition', '3.except']},
   'Header': ['1.Modle', '2.Class', '3.Object'],
   ...}

I attempt to repalce the strings in mydict with the appropriate in mylist 我尝试用mylist的适当字符串mydict mydict中的字符串

I can figure out '2B1D0.Data.md' has the shortest length, So I slice the keyward 'Data' 我可以弄清楚'2B1D0.Data.md'的长度最短,所以我将键控“ Data”切成片

In [82]: '2B1D0.Data.md'[-7:-3]
Out[82]: 'Data'

The dict has both a nested list and nested dict. 字典同时具有嵌套列表和嵌套字典。
So I write a iteration function with type checking 所以我写了一个带有type checking的迭代函数
if an item's value isinstance(value,list) , renew that value, 如果项目的值为isinstance(value,list) ,则更新该值,
if an item's value isinstance(value, dict) ,call the function replace_ele() to continue. 如果项目的值为isinstance(value, dict) ,则调用函数replace_ele()继续。

I name string in mylist as str_of_list, while string in mydict as str_of_dict for readable concerns. 我将mylist中的字符串命名为str_of_list,而mydict中的字符串命名为str_of_dict以便于阅读。

#replace one string in mydict
def replace_ele(mydict, str_of_list):
    for key, value in mydict.items():
        if isinstance(value, list): #type checking
            for str_of_dict in value:
                #replace str_of_dict with str_of_list
                if str_of_list[-7:-3].lower() == str_of_dict[-4:]: #[-7:-3] the shortest length
                    value.remove(str_of_dict)
                    value.append(str_of_list)
                    value.sort()
                    mydict[key] = value
        #iteration if a dict
        if isinstance(value, dict):
            replace_ele(value,str_of_list)

for str_of_list in mylist:
    replace_ele(mydict, str_of_list)

Then running and outputs: 然后运行并输出:

Out[117]:
{'Body': {'Data': ['2B1D1.Primitive.md',
   '2B1D2.Operator.md',
   '2B2D3.Container.md'],
  'Statement': ['2B2S0.Function.md',
   '2B2S0.Function.md',
   '2B2S1.Controlled_Loop.md',
   '2B2S3.Except.md']},
 'Header': ['1.Modle', '1H2.Class.md', '1H3.MetaObject.md']
 ....}

I assume that such a problem can be solved with less codes. 我认为可以用更少的代码解决这个问题。 However, I cannot find that solution with the limited knowledge. 但是,我在知识有限的情况下找不到该解决方案。

How to accomplish it elegantly? 如何优雅地完成它?

My suggestion is that you create a function to reduce element of mylist and elements in lists of mydict values to the same format: 我的建议是创建一个函数,以将mylist元素和mydict值列表中的元素减少为相同格式:

For example, you can split by '.' 例如,您可以用'.'分隔'.' character, take the second field, convert it to lower case: 字符,将第二个字段转换为小写:

def f(s):
    return s.split('.')[1].lower()

Eg: 例如:

>>> f('2B2S1.Controlled_Loop.md')
'controlled_loop'
>>> f('1.controlled_loop')
'controlled_loop'

Now, from mylist create a dict to hold replacements: 现在,从mylist创建一个dict来保存替换:

mylist_repl={f(x): x for x in mylist}

ie mylist_repl contains key: value items such as 'metaobject': '1H3.MetaObject.md' . mylist_repl包含key: value项,例如'metaobject': '1H3.MetaObject.md'

With dict mylist_repl and function f , it is easy to transform a list from mydict to the desired value, example: 使用dict mylist_repl和函数f ,可以很容易地将列表从mydict转换为所需的值,例如:

>>> [mylist_repl[f(x)] for x in ['1.primitive', '2.operator', '3.container']]
['2B1D1.Primitive.md', '2B1D2.Operator.md', '2B2D3.Container.md']

Also note that this dictionary lookup is more efficient (ie: faster) than a nested for loop! 还要注意,此字典查找比嵌套的for循环更有效(即:更快)!

If you have different replacement logic, you probably only need to change how f maps items from two different sets to a common key. 如果您有不同的替换逻辑,则可能只需要更改f将项目从两个不同的集合映射到一个公共密钥的方式。

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

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