Python使用理解来整合字典键和值

时间:2017-07-12 05:44:27

标签: python dictionary list-comprehension consolidation

如何使用python COMPREHENSION

整合以下内容

FROM(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(以元组为键的词典列表和'server#'列为值

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

2 个答案:

答案 0 :(得分:4)

需要能够为您的字典设置默认值并多次使用相同的键可能会使字典理解有点笨拙。我喜欢这样的事情:

defaultdict可能有所帮助:

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'])

如果您希望最后有一个标准字典(实际上我真的没有找到合理的理由),您可以使用dict.setdefault来创建一个空键表,其中该键尚不存在:

dct = {}

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

documentation on defaultdict (vs. setdefault)

  

这种技术比同等技术更简单,更快捷   使用dict.setdefault()

答案 1 :(得分:1)

由于积累效应,很难通过列表理解来实现。但是,可以使用按键排序的列表itertools.groupby(使用相同的key函数进行排序和分组)。

然后通过组密钥提取列表推导中的服务器信息和前缀。将结果(组密钥,服务器列表)传递给字典理解,然后就可以了。

import itertools

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'}
]


sortfunc = lambda x : (x['os'],x['archive'])

result = {k:[x['server'] for x in v] for k,v in itertools.groupby(sorted(lst,key=sortfunc),key = sortfunc)}


print(result)

我明白了:

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

请记住,这不是因为它可以写在一行中,因为它更有效率。 defaultdict方法并不需要排序。