在日期键上合并两个词典

时间:2015-08-10 19:33:06

标签: python date merge ordereddictionary

假设您有两个(有序的)dicts,从(字符串)日期映射到十进制数字,如下所示:

adata = OrderedDict(
    [('2014-01-06', Decimal('14560.810')), 
     ('2014-01-13', Decimal('17867.040')), 
     ('2013-12-30', Decimal('8941.440')), 
     ('2014-02-10', Decimal('17737.630')), 
     ('2014-02-03', Decimal('14450.870')), 
     ('2014-01-20', Decimal('15595.400')),
     ('2014-02-24', Decimal('6290.760')), 
     ('2014-01-27', Decimal('14619.390'))]) 

bdata=  OrderedDict(
    [('2013-01-27', Decimal('12173.170')), 
     ('2012-12-31', Decimal('14447.010')),  
     ('2014-02-24', Decimal('14861.870')),  
     ('2014-02-27', Decimal('861.870'))])

如何根据以下规则将adatabdata合并:

  1. 按月和日合并,而不是年份。
  2. 如果adata中的bdata中的密钥在第2个位置分配bdata[key]的值,则在其中指定值0。
  3. 退回此处,但按日期排序。
  4. Decimal可以用浮动替换。
  5. 我期待这个输出:

    cdata =  OrderedDict(
        [('2013-12-30', (Decimal('8941.440'), 0)),
         ('2012-12-31', (0, Decimal('14447.010'))),          
         ('2014-01-06', (Decimal('14560.810'), 0)),
         ('2014-01-13', (Decimal('17867.040'), 0)), 
         ('2014-01-20', (Decimal('15595.400'), 0)),
         ('2014-01-27', (Decimal('14619.390'), Decimal('12173.170'))), 
         ('2014-02-03', (Decimal('14450.870'), 0)), 
         ('2014-02-10', (Decimal('17737.630'), 0)), 
         ('2014-02-24', (Decimal('6290.760'), Decimal('14861.870'))),
         ('2014-02-27', (0, Decimal('861.870'))) ])
    

    我尝试了以下操作,但是我没有得到我想要的输出。

    cdata = OrderedDict()
    for key in adata.keys() + bdata.keys():
    if not cdata.has_key(key):
        try:
            val_b = adata[key]
        except KeyError:
            val_b = 0
        try:
            val_c = bdata[key]
        except KeyError:
            val_c = 0
        cdata[key] = (val_b, val_c)
    

2 个答案:

答案 0 :(得分:0)

尝试在最后添加:

cdata = OrderedDict([(key, cdata[key]) for key in sorted(cdata)])

它将按日期字符串对合并的字典进行排序。

答案 1 :(得分:0)

要让它按月和日正确排序,您需要一个自定义比较器:

month_day = lambda x: tuple(map(int,x[-5:].split('-')))

def month_day_cmp(a,b):
    a = month_day(a)
    b = month_day(b)
    def cmp(a,b,index):
        if index > 1: return 0
        if a[index] > b[index]:
            return 1
        elif a[index] < b[index]:
            return -1
        else:
            return cmp(a,b,index+1)
    return cmp(a, b, 0)


for k,v in OrderedDict(sorted(cdata.items(),cmp=month_day_cmp, key=lambda x: x[0])).items():
    print '{} -> {}'.format(k,v)

从问题中如何定义cdata键并不完全清楚。 例如,如果您有两个日期相同的月份和日期但不同的年份 - 我们在密钥中使用哪一年?如果这很重要,您将需要更多代码。