0

I have a number of outputs (collected from db queries) and mapped into a dictionaries with key:value pairs db_column: value

Sample data that i want to combine:

dicts1 = [ 
      {'K1': 'kval', 'L1': 'Lval', 'F1': None, 'F2': None, 'F3': 'ERR1'},
      {'K1': 'kval', 'L1': 'Lval', 'F1': None, 'F2': None, 'F3': 'ERR1'},
      {'F1': None, 'F2': None, 'F3': 'ERR2'}]

Now i would like to combine those dictionaries into single one but values from F1, F2, F3 shall be concatenated with ; if not None. If it's None then leve value as it is. Ideally: if some key exists in special_key=('F1', 'F2', 'F3') then concatenate..

result_dict: {'K1': 'kval', 'L1': 'Lval', 'F1': None, 'F2': None, 'F3': 'ERR1;ERR2;ERR3'}

on the base of question asked in: Python - Combine two dictionaries, concatenate string values? i figured out some piece of code and get stucked

def concat_dict(*dicts):
    keys = set().union(*dicts)
    print "keys: ", keys
    outdict = {}
    for k in keys:
        print "key: ", k
        for dic in dicts:
            print k, dic.get(k)
            outdict[k] = dic.get(k)

Any help appreciated.

Community
  • 1
  • 1
modzello86
  • 433
  • 7
  • 16

2 Answers2

0

First, concat_dict is not returning a new dict or modifying an existing dict. So you won't get anything out.

Second, you need to pass in the list of special keys.

Third, you need to decide what to do with keys. Currently concat_dict is overwriting any values it comes to based on order. It looks like you want to keep non-empty values regardless of whether the key is special.

The following function will get you what you want, but I don't claim it's optimum. You could probably pass another function to customize how to handle special keys if you wanted more customization.

def concat_dict(special_keys, *dicts):
    keys = set().union(*dicts)
    outdict = {}
    for k in keys:
        for dic in dicts:
            if dic.has_key(k):
                if k in special_keys:
                    if outdict.has_key(k) and dic[k] is not None:
                        outdict[k] = outdict[k] + ";" + dic[k]
                    else:
                        outdict[k] = dic[k]
                else:
                    outdict[k] = dic.get(k)
    return outdict
bob0the0mighty
  • 782
  • 11
  • 28
  • `dicts1 = [{'K1': 'kval', 'L1': 'Lval', 'F1': None, 'F2': None, 'F3': 'ERR1'}, {'K1': 'kval', 'L1': 'Lval', 'F1': None, 'F2': None, 'F3': 'ERR1'}, {'F1': None, 'F2': None, 'F3': None}]` will result in `F3`: `None` but thanx anyway, i'll work on Your solution. In addition has_key is depreciated -> http://stackoverflow.com/questions/1323410/has-key-or-in – modzello86 Feb 10 '16 at 14:14
  • I generally use 2.7 since some libraries I use don't have the best 3.X support. – bob0the0mighty Feb 10 '16 at 14:27
0

Is this what you're looking for?

dicts1 = [
      {'K1': 'kval', 'L1': 'Lval', 'F1': None, 'F2': None, 'F3': 'ERR1'},
      {'K1': 'kval', 'L1': 'Lval', 'F1': None, 'F2': None, 'F3': 'ERR1'},
      {'F1': None, 'F2': None, 'F3': 'ERR2'}]

special_keys = ['F1', 'F2', 'F3']

def concat_dict(dicts1):
    outdict = {}
    for dictionary in dicts1:
        for key, value in dictionary.items():
            #FOr special keys
            if key in special_keys:
                #Check first if key is already inserted in outdict
                if key not in outdict or not outdict[key]:
                    outdict[key] = value
                #Else only if value is not None, do concatenation
                elif value:
                    outdict[key] = '{prepend};{newValue}'.format(prepend=outdict[key], newValue=value)
            else:
                outdict[key] = value

    return outdict

Outputs

{'K1': 'kval', 'F1': None, 'F3': 'ERR1;ERR1;ERR2', 'L1': 'Lval', 'F2': None}
Obsidian
  • 515
  • 3
  • 10
  • That seems to be fine. I'll try to go as close Dict-comprehension as possible but for the starter this could be accepted. Thanks! – modzello86 Feb 10 '16 at 15:07