首页 > 解决方案 > 在Python中合并后字典键乱序

问题描述

合并两个字典后,结果字典的子键是无序的。子键是月份 ['jan', 'feb', 'mar', ... , 'dec']。在某些情况下,原始字典可能不包含子键(月份),因此输出会因合并而无序。

所以我有两个字典都具有下一个结构 {Model:{'Jan':[1], 'Feb':[2], Jun: [5], ...}

正如您在此示例中所看到的,某些子键(月份)未表示,因此在原始字典中找不到它们。但是,我需要的是合并的字典来保持每月的订单,不管原始字典的外观如何。

合并函数:

def merge_dicts(dict1, dict2):
    '''Marge two dicts by adding up (accumulating) values in each key.

    Returns: A merge (addition) of two dictionaries by adding values of same keys
    '''
   # Merge dictionaries and add values of same keys
    out = {**dict1, **dict2}
    for key, value in out.items():
        if key in dict1 and key in dict2:
            out[key] = [value, dict1[key]]
            #Things got harder, out[key] appends in list of list of list... no itertools can help here.
            lst = [] #the one dimensional list to fix the problem of list of list with out[key]
            for el in out[key]:
                try:
                #if inside out[key] there is a list of list we split it
                    for sub_el in el:
                        lst.append(sub_el)
                except:
                #if inside out[key] there is only a single float
                    lst.append(el)
            #Replace the old key with the one dimensional list
            out[key] = lst
    return out

我如何合并它:

for c in range(len([*CMs_selection.keys()])):
    if c == 0:
        #First merge, with dict0 & dict1
        merged_dict = {cm:merge_dicts(CMs_selection[[*CMs_selection.keys()][c]][cm], CMs_selection[[*CMs_selection.keys()][c + 1]][cm]) 
                       for cm in CMs_selection[[*CMs_selection.keys()][0]]}

    elif c > 0 and c < (len(years) - 1):
        #Second merge to n merge, starting with dict_merged and dict 2
        merged_dict = {cm:merge_dicts(merged_dict[cm], CMs_selection[[*CMs_selection.keys()][c + 1]][cm]) 
                       for cm in CMs_selection[[*CMs_selection.keys()][0]]}


现在,在尝试了所有可能的合并之后,我总是得到这个结果。

{'Model1': {'Jan': [-0.0952586755156517,
   0.1015196293592453,
   -0.10572463274002075],
  'Oct': [-0.02473766915500164,
   0.0678798109292984,
   0.08870666474103928,
   -0.06378963589668274],
  'Nov': [-0.08730728179216385,
   0.013518977910280228,
   0.023245899006724358,
   -0.03917887806892395],
  'Jul': [-0.07940272241830826, -0.04912888631224632, -0.07454635202884674],
  'Dec': [-0.061335086822509766, -0.0033914903178811073, 0.09630533307790756],
  'Mar': [0.029064208269119263, 0.11327305436134338, 0.009556809440255165],
  'Apr': [-0.04433680325746536, -0.08620205521583557],
  'Jun': [-0.036688946187496185, 0.05543896555900574, -0.07162825018167496],
  'Aug': -0.03712410107254982,
  'Sep': [0.007421047426760197, 0.008665643632411957],
  'Feb': [-0.02879650704562664, 0.013025006279349327]},
 'Model2': {'Feb': -0.05173473060131073,
  'Jun': [-0.09126871824264526,
   -0.09009774029254913,
   0.10458160936832428,
   -0.09445420652627945,
   -0.04294373467564583],
  'Aug': [-0.07917020469903946, 0.011026041582226753],
  'Oct': [-0.10164830088615417, ....

……

以乱月。请帮我!

标签: python-3.xsortingdictionarymergekey

解决方案


如果我们只关注合并字典,首先,我们需要定义正常的月份顺序,然后按该顺序进行合并,因为 Python 不知道这个顺序。如果第一个字典中不存在“Mar”,则不能在“Feb”和“Apr”之间添加“Mar”。所以,我们需要自己定义顺序。

此外,您需要两种不同的解决方案来合并浮点值和合并列表。我在我的解决方案中添加了mode参数。

def merge_dicts(list_of_dicts, mode):
    keys = set(key for d in list_of_dicts for key in d.keys())
    months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
    ordered_keys = [month for month in months if month in keys]

    out = {}
    for key in ordered_keys:
        out[key] = []
        for d in list_of_dicts:
            if key in d:
                if mode == "append":
                    out[key].append(d[key]) 
                elif mode == "extend":
                    out[key].extend(d[key])

    return out


CMs_selection = {2006: {'Model1': {'Jan': -0.1, 'Oct': -0.063}, 'Model2': {'Feb': -0.051, 'Jun': -0.04, 'Oct': 0.07}, 'Model3': {'Mar': -0.030, 'Jun': 0.02, 'Aug': 0.0561,}, 'Model4': {'Feb': -0.026, 'Dec': -0.06}}, 2007: {'Model1': {'Jul': -0.07, 'Oct': 0.8, 'Nov': 0.38, 'Dec': 0.1}, 'Model2': {'Jun': -0.09, 'Aug': -0.079, 'Sep': -0.7}}}

for key in CMs_selection:
    CMs_selection[key] = merge_dicts(CMs_selection[key].values(), "append")

print(CMs_selection)

result = merge_dicts(CMs_selection.values(), "extend")
print(result)

输出:

{2006: {'Jan': [-0.1], 'Feb': [-0.051, -0.026], 'Mar': [-0.03], 'Jun': [-0.04, 0.02], 'Aug': [0.0561], 'Oct': [-0.063, 0.07], 'Dec': [-0.06]}, 2007: {'Jun': [-0.09], 'Jul': [-0.07], 'Aug': [-0.079], 'Sep': [-0.7], 'Oct': [0.8], 'Nov': [0.38], 'Dec': [0.1]}}
{'Jan': [-0.1], 'Feb': [-0.051, -0.026], 'Mar': [-0.03], 'Jun': [-0.04, 0.02, -0.09], 'Jul': [-0.07], 'Aug': [0.0561, -0.079], 'Sep': [-0.7], 'Oct': [-0.063, 0.07, 0.8], 'Nov': [0.38], 'Dec': [-0.06, 0.1]}

推荐阅读