Search code examples
pythondictionarylist-comprehensionconsolidation

Python consolidate dictionary keys and values using comprehension


How do I CONSOLIDATE the following using python COMPREHENSION

FROM (list of dicts)

[
 {'server':'serv1','os':'Linux','archive':'/my/folder1'}
 ,{'server':'serv2','os':'Linux','archive':'/my/folder1'}
 ,{'server':'serv3','os':'Linux','archive':'/my/folder2'}
 ,{'server':'serv4','os':'AIX','archive':'/my/folder1'}
 ,{'server':'serv5','os':'AIX','archive':'/my/folder1'}
]

TO (list of dicts with tuple as key and list of 'server#'s as value

[
 {('Linux','/my/folder1'):['serv1','serv2']}
 ,('Linux','/my/folder2'):['serv3']}
 .{('AIX','/my/folder1'):['serv4','serv5']}
]

Solution

  • the need to be able to set default values to your dictionary and to have the same key several times may make a dict-comprehension a bit clumsy. i'd prefer something like this:

    a defaultdict may help:

    from collections import defaultdict
    
    lst = [
     {'server':'serv1','os':'Linux','archive':'/my/folder1'},
     {'server':'serv2','os':'Linux','archive':'/my/folder1'},
     {'server':'serv3','os':'Linux','archive':'/my/folder2'},
     {'server':'serv4','os':'AIX','archive':'/my/folder1'},
     {'server':'serv5','os':'AIX','archive':'/my/folder1'}
    ]
    
    dct = defaultdict(list)
    
    for d in lst:
        key = d['os'], d['archive']
        dct[key].append(d['server'])
    

    if you prefer to have a standard dictionary in the end (actually i do not really see a good reason for that) you could use dict.setdefault in order to create an empty list where the key does not yet exist:

    dct = {}
    
    for d in lst:
        key = d['os'], d['archive']
        dct.setdefault(key, []).append(d['server'])
    

    the documentation on defaultdict (vs. setdefault):

    This technique is simpler and faster than an equivalent technique using dict.setdefault()