【问题标题】:Convert keys of a nested dictionary to upper case将嵌套字典的键转换为大写
【发布时间】:2020-05-08 13:00:14
【问题描述】:

有一本字典:

data = {'Common': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
         'Man': 'handsome',
         'Woman': {'feature': 'pretty', 'weight': 50},
         'Dog': {'feature': 'barks', 'height': 10, 'weight': 20}}

只想将字典键转换为大写。

尝试了以下代码:

d = {}
d1 = {}
for k, v in data.items():
    if isinstance(v, dict):
        for i, j in v.items():
            d1[i.upper()] = j
        d[k.upper()] = d1
    else:
        d[k.upper()] = v

print(d)

...生成带有不必要的键和高度和重量合理化的输出,如下所示:

{'COMMON': {'HEIGHT': 10, 'WEIGHT': 20, 'MEASURE': ['cm', 'kg'], 'FEATURE': 'barks'}, 
    'MAN': 'handsome', 
  'WOMAN': {'HEIGHT': 10, 'WEIGHT': 20, 'MEASURE': ['cm', 'kg'], 'FEATURE': 'barks'}, 
    'DOG': {'HEIGHT': 10, 'WEIGHT': 20, 'MEASURE': ['cm', 'kg'], 'FEATURE': 'barks'}}

我的预期输出是:

{'COMMON': {'HEIGHT': 165, 'WEIGHT': 70, 'MEASURE': ['cm', 'kg']},
 'MAN': 'handsome',
 'WOMAN': {'FEATURE': 'pretty', 'WEIGHT': 50},
 'DOG': {'FEATURE': 'barks', 'HEIGHT': 10, 'WEIGHT': 20}}
  1. 我哪里出错了?
  2. {{i.upper(): j} if isinstance(j, dict) else {k.upper(): v} for k, v in data.items() for i, j in v.items()} 这样的正确字典理解是什么?

【问题讨论】:

    标签: python string dictionary for-loop dictionary-comprehension


    【解决方案1】:

    您可以这样做,使用所需的密钥复制到其他dict

    data = {'Common': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
            'Man': 'handsome',
            'Woman': {'feature': 'pretty', 'weight': 50},
            'Dog': {'feature': 'barks', 'height': 10, 'weight': 20}}
    data2 = {}
    for k in data.keys():
        data2[k.upper()] = data[k]
    

    更新: 如果您不仅要更改级别 1 上的键,则应使用递归函数:

    data = {'Common': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
            'Man': 'handsome',
            'Woman': {'feature': 'pretty', 'weight': 50},
            'Dog': {'feature': 'barks', 'height': 10, 'weight': 20}}
    
    def keys_to_upper(dict1):
        dict2 = {}
        for k in dict1.keys():
            if isinstance(dict1[k], dict):
                dict2[k.upper()] = keys_to_upper(dict1[k])
            else:
                dict2[k.upper()] = dict1[k]
        return dict2
    
    d2 = keys_to_upper(data)
    

    【讨论】:

      【解决方案2】:

      您的代码的问题是,如果值是字典,您正在重新分配 d1。你可以使用copy.deepcopy()来解决这个问题:

      代码:

      from copy import deepcopy
      
      d = {}
      d1 = {}
      for k, v in data.items():
          if isinstance(v, dict):
              for i, j in v.items():
                  d1[i.upper()] = j
              d[k.upper()] = deepcopy(d1)
          else:
              d[k.upper()] = v
      

      输出:

      >>> d
      {'COMMON': {'HEIGHT': 165, 'WEIGHT': 70, 'MEASURE': ['cm', 'kg']},
       'MAN': 'handsome',
       'WOMAN': {'FEATURE': 'pretty', 'WEIGHT': 50},
       'DOG': {'FEATURE': 'barks', 'HEIGHT': 10, 'WEIGHT': 20}}
      

      或者,作为字典理解:

      >>> {k.upper(): {i.upper(): j for i, j in v.items()} if isinstance(v, dict) else v for k, v in data.items()}
      {'COMMON': {'HEIGHT': 165, 'WEIGHT': 70, 'MEASURE': ['cm', 'kg']},
       'MAN': 'handsome',
       'WOMAN': {'FEATURE': 'pretty', 'WEIGHT': 50},
       'DOG': {'FEATURE': 'barks', 'HEIGHT': 10, 'WEIGHT': 20}}
      

      【讨论】:

      • 为什么字典理解中不需要deepcopy
      • @reservoirinvest 因为不是使用 for 循环创建一个名为 d1 的字典,然后将其与原始键配对,而是使用嵌套字典理解来构建它,因此我们从不分配它是一个变量。
      • @reservoirinvest 如果您在if isinstance(v, dict): 之后使用d[k.upper()] = {i.upper(): j for i, j in v.items()},则可以从原始文件中删除deepcopy
      【解决方案3】:

      列表理解更快,因为它针对 Python interpreter 进行了优化,可以在 looping 期间发现可预测的模式。除了 list comprehensions 的语法优势之外,它们通常与 map 的同等使用一样快或更快。

      data = {'Common': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
              'Man': 'handsome',
              'Woman': {'feature': 'pretty', 'weight': 50},
              'Dog': {'feature': 'barks', 'height': 10, 'weight': 20}}
      
          for k, v in data.items():
            if isinstance(v, dict):
              data[k.upper()] = data.pop(k)
      

      输出>

      data = {'COMMON': {'height': 165, 'weight': 70, 'measure': ['cm', 'kg']},
              'Man': 'handsome',
              'WOMAN': {'feature': 'pretty', 'weight': 50},
              'DOG': {'feature': 'barks', 'height': 10, 'weight': 20}}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-12-05
        • 1970-01-01
        • 2020-09-03
        • 2013-12-07
        • 2014-11-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多