Python 使用理解合并字典键和值
Python consolidate dictionary keys and values using comprehension
我如何使用python COMPREHENSION
巩固以下内容
FROM(字典列表)
[
{'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(以元组为键的字典列表和“服务器#”列表作为值
[
{('Linux','/my/folder1'):['serv1','serv2']}
,('Linux','/my/folder2'):['serv3']}
.{('AIX','/my/folder1'):['serv4','serv5']}
]
需要能够为您的字典设置默认值并多次使用相同的键可能会使字典理解有点笨拙。我更喜欢这样的东西:
一个 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
):
This technique is simpler and faster than an equivalent technique
using dict.setdefault()
由于积累效应,列表理解很难实现。但是,可以在按键排序的列表上使用 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
方法不需要排序。
我如何使用python COMPREHENSION
巩固以下内容FROM(字典列表)
[
{'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(以元组为键的字典列表和“服务器#”列表作为值
[
{('Linux','/my/folder1'):['serv1','serv2']}
,('Linux','/my/folder2'):['serv3']}
.{('AIX','/my/folder1'):['serv4','serv5']}
]
需要能够为您的字典设置默认值并多次使用相同的键可能会使字典理解有点笨拙。我更喜欢这样的东西:
一个 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
):
This technique is simpler and faster than an equivalent technique using dict.setdefault()
由于积累效应,列表理解很难实现。但是,可以在按键排序的列表上使用 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
方法不需要排序。