【问题标题】:Rearranging levels of a nested dictionary in python在python中重新排列嵌套字典的级别
【发布时间】:2015-10-29 22:39:06
【问题描述】:

是否有一个库可以帮助我完成重新排列嵌套字典级别的任务

例如:从这里:

{1:{"A":"i","B":"ii","C":"i"},2:{"B":"i","C":"ii"},3:{"A":"iii"}}

到这里:

{"A":{1:"i",3:"iii"},"B":{1:"ii",2:"i"},"C":{1:"i",2:"ii"}}

即交换了 3 级词典上的前两个级别。所以不是 1 映射到 A 和 3 映射到 A,我们有 A 到 1 和 3 的映射。

解决方案应该适用于任意深度,并从一个级别移动到任何其他级别。

【问题讨论】:

标签: python data-structures


【解决方案1】:
>>> d = {1:{"A":"i","B":"ii","C":"i"},2:{"B":"i","C":"ii"},3:{"A":"iii"}}
>>> keys = ['A','B','C']
>>> e = {key:{k:d[k][key] for k in d if key in d[k]} for key in keys}
>>> e
{'C': {1: 'i', 2: 'ii'}, 'B': {1: 'ii', 2: 'i'}, 'A': {1: 'i', 3: 'iii'}}

感谢上帝对字典的理解

【讨论】:

    【解决方案2】:

    考虑这一点的一种方法是将您的数据视为(命名)数组并进行转置。实现此目的的一个简单方法是使用数据分析包 Pandas:

    import pandas as pd
    
    df = pd.DataFrame({1: {"A":"i","B":"ii","C":"i"},
                       2: {"B":"i","C":"ii"},
                       3: {"A":"iii"}})
    df.transpose().to_dict()
    
    {'A': {1: 'i', 2: nan, 3: 'iii'},
     'B': {1: 'ii', 2: 'i', 3: nan},
     'C': {1: 'i', 2: 'ii', 3: nan}}
    

    【讨论】:

    • 一个不错的选择,但这只有在您的字典的值可以读入 pandas 时才有效。
    • 优雅,但用 nan 污染了你的新字典(还是很喜欢)。
    【解决方案3】:

    我并不真正关心我的应用程序的性能,所以我没有费心检查它的效率。它基于冒泡排序,所以我的猜测是~O(N^2)。

    也许这很复杂,但基本上下面的工作方式是: - 提供 dict_swap_index 一个嵌套字典和一个列表。列表的格式应为 [i,j,k]。长度应该是字典的深度。每个元素对应于您要将每个元素移动到的位置。例如[2,0,1] 表示将元素 0 移动到位置 2,元素 1 移动到位置 0,元素 2 移动到位置 1。 - 此函数对订单列表和 dict_ 执行冒泡排序,调用 deep_swap 交换订单列表中正在交换的字典级别 - deep_swap 递归调用自身以查找提供的级别并返回已重新排序的字典 - 调用 swap_two_level_dict 来交换字典中的任意两个级别。

    本质上,这个想法是对字典执行冒泡排序,而不是交换字典中的列表中的元素。

    from collections import defaultdict
    def dict_swap_index(dict_, order):
        for pas_no in range(len(order)-1,0,-1):
            for i in range(pas_no):
                if order[i] > order[i+1]:
                    temp = order[i]
                    order[i] = order[i+1]
                    order[i+1] = temp
                    dict_ = deep_swap(dict_, i)
        return dict_, order
    
    def deep_swap(dict_, level):
        dict_ = deepcopy(dict_)
        if level==0:
            dict_ = swap_two_level_dict(dict_)
        else:
            for key in dict_:
                dict_[key] = deep_swap(dict_[key], level-1)
        return dict_
    
    def swap_two_level_dict(a):
        b = defaultdict(dict)
        for key1, value1 in a.items():
            for key2, value2 in value1.items():
                b[key2].update({key1: value2})
        return b
    

    例如

    test_dict = {'a': {'c': {'e':0, 'f':1}, 'd': {'e':2,'f':3}}, 'b': {'c': {'g':4,'h':5}, 'd': {'j':6,'k':7}}}
    result = dict_swap_index(test_dict, [2,0,1])
    result
    (defaultdict(dict,
                 {'c': defaultdict(dict,
                              {'e': {'a': 0},
                               'f': {'a': 1},
                               'g': {'b': 4},
                               'h': {'b': 5}}),
                  'd': defaultdict(dict,
                              {'e': {'a': 2},
                               'f': {'a': 3},
                               'j': {'b': 6},
                               'k': {'b': 7}})}),
     [0, 1, 2])
    

    【讨论】:

      猜你喜欢
      • 2021-10-26
      • 2012-10-25
      • 2022-01-25
      • 2015-11-12
      • 1970-01-01
      • 2019-12-04
      • 2018-03-17
      • 1970-01-01
      相关资源
      最近更新 更多