【问题标题】:How to convert nested dictionaries into Python tuples?如何将嵌套字典转换为 Python 元组?
【发布时间】:2021-06-14 15:17:21
【问题描述】:

我想将嵌套字典转换为 Python 元组,但我发现的所有示例都不适合我的情况。这就是字典的样子:

d = {'default': {'USD': {'value': 490.0, 'quantity': 490.0}},
     'expert': {'USD': {'value': 500.0, 'quantity': 500.0}}}

想要的结果:

{('default', 'value'): {'USD': 490.0},
 ('default', 'quantity'): {'USD': 490.0},
 ('expert', 'value'): {'USD': 500.0},
 ('expert', 'quantity'): {'USD': 500.0}
}

这个想法是像这样创建一个多索引数据框:

pd.DataFrame(tuple)

        default             expert
        value   quantity    value   quantity
USD     490.0   490.0       500.0   500.0

我做了什么

使用 (see this question) 可以获得稍微不同的结果:

{(outerKey, innerKey): values for outerKey, innerDict in d.items() 
 for innerKey, values in innerDict.items()}

这给出了:

{('default', 'USD'): {'value': 490.0, 'quantity': 490.0},
 ('expert', 'USD'): {'value': 500.0, 'quantity': 500.0}}

但正如您所见,数据框没有所需的结构:

            default expert
            USD     USD
value       490.0   500.0
quantity    490.0   500.0

【问题讨论】:

    标签: python


    【解决方案1】:

    你可以像这样使用 smth,它看起来很丰富,但效果和预期的一样:

    d = {'default': {'USD': {'value': 490.0, 'quantity': 490.0}},
         'expert': {'USD': {'value': 500.0, 'quantity': 500.0}}}
    
    new_d = {}
    
    for key, value in d.items():
        for key1, value1 in value.items():
            for key2, value2 in value1.items():
                new_d[(key, key2)] = {key1: value2}
    

    【讨论】:

      【解决方案2】:

      一般来说,我会将初始 dict 展平,将其加载到 DataFrame 中,然后旋转 DataFrame:

      # flatten:
      def flatten(val):
          if isinstance(val, list):
              return val
          elif isinstance(val, dict):
              return [(k, *v) for k, value in val.items()
                       for v in flatten(value)]
          return ((val,),)
      
      # print(flatten(d))          # uncomment for traces
      
      # load into a raw DataFrame:
      df = pd.DataFrame(flatten(d))
      # print(df)                  # uncomment for traces
      
      # We can now choose what should be the index, columns and values
      df = df.pivot(1, [0,2], 3).rename_axis(index=None, columns=(None, None))
      

      它按预期给出:

          default          expert         
            value quantity  value quantity
      USD   490.0    490.0  500.0    500.0
      

      并且痕迹是(未注释时):

      [('default', 'USD', 'value', 490.0), ('default', 'USD', 'quantity', 490.0),
       ('expert', 'USD', 'value', 500.0), ('expert', 'USD', 'quantity', 500.0)]
      
               0    1         2      3
      0  default  USD     value  490.0
      1  default  USD  quantity  490.0
      2   expert  USD     value  500.0
      3   expert  USD  quantity  500.0
      

      【讨论】:

      • 由于某种原因,pivot 函数返回IndexError: Too many levels: Index has only 2 levels, not 3。这是我的跟踪[('default', 'USD', 'value', 490.0), ('default', 'USD', 'quantity', 490.0), ('expert', 'USD', 'value', 500.0), ('expert', 'USD', 'quantity', 500.0)]
      • 我忘了说这也是错误信息的一部分ValueError: 2 is not in list
      【解决方案3】:

      我通过在问题中的示例中添加带有secInnerDict 的嵌套级别找到了我自己问题的答案:

      {(outerKey, secinnerKey): {innerKey:secvalues} for outerKey, innerDict in total.items() for innerKey, secInnerDict in innerDict.items() for secinnerKey, secvalues in secInnerDict.items()}
      

      返回:

      {('default', 'value'): {'USD': 490.0},
       ('default', 'quantity'): {'USD': 490.0},
       ('expert', 'value'): {'USD': 500.0},
       ('expert', 'quantity'): {'USD': 500.0}}
      

      【讨论】:

      • 我没有提供嵌套列表理解,因为听说它不是推荐,因为阅读复杂
      猜你喜欢
      • 1970-01-01
      • 2022-06-14
      • 2013-12-07
      • 2017-01-20
      • 2014-03-17
      • 1970-01-01
      • 2019-12-28
      • 1970-01-01
      相关资源
      最近更新 更多