从字典中提取匹配字段

Extract matching fileds from dictonary

有没有更聪明的方法可以将 OrderedDict 中的所有键提取到新字典中?

例如:我将所有匹配到'pre'的key收集到字典'cfg_pre'中。我试过这个(有效):

#!/usr/bin/env python
import collections

dl=collections.OrderedDict()

dl ={ 
        'pre_enable': True, 
        'pre_path': '/usr/bin/pre_script.sh', 
        'pre_args': '-la -w --dir', 
        'post_enable': True, 
        'post_path': '/usr/bin/post_script.sh', 
        'fail_enable': True, 
        'fail_path': '/usr/bin/failure_script.sh', 
        'fail_args': '--debug 4'
        }

cfg_pre = dict((k,v) for k, v in dl.items() if 'pre' in k)
cfg_post= dict((k,v) for k, v in dl.items() if 'post' in k)
cfg_fail=dict((k,v) for k, v in dl.items() if 'fail' in k)


print (cfg_pre)
print ("---")
print(cfg_post)
print ("---")
print(cfg_fail)
print ("---")

dl-dict 中的键总是以 pre、post 或 fail 开头。 谢谢 ;)

对于这样的问题,三行就足够了。

听写理解会更清晰一些:

cfg_pre = {k: v for k, v in dl.items() if 'pre' in k}
cfg_post = {k: v for k, v in dl.items() if 'post' in k}
cfg_fail = {k: v for k, v in dl.items() if 'fail' in k}

您也可以像这样删除冗余数据:

cfg_pre = {k.replace('pre_', ''): v for k, v in dl.items() if 'pre' in k}
cfg_post = {k.replace('post_', ''): v for k, v in dl.items() if 'post' in k}
cfg_fail = {k.replace('fail_', ''): v for k, v in dl.items() if 'fail' in k}

字典将更加一致,prepostfail将只存储在变量名中:

cfg_pre = {'args': '-la -w --dir', 'enable': True, 'path': '/usr/bin/pre_script.sh'}
cfg_post = {'enable': True, 'path': '/usr/bin/post_script.sh'}
cfg_fail = {'args': '--debug 4', 'enable': True, 'path': '/usr/bin/failure_script.sh'}

编辑 -> 更新以满足您的需要

如果您想概括,我建议您按方法分组。像 :

import itertools as it

#define a function to split your universe (here the beginning of your keys)
def keyfunc(key):
    return key.split('_')[0]

#group by prefixes
groups = {k:list(g) for k,g in it.groupby(dl, keyfunc)}

#build your output
output = {g:[(key,dl[key]) for key in v] for g,v in groups.items()}

您将得到以下输出:

{'fail': [('fail_enable', True),
  ('fail_path', '/usr/bin/failure_script.sh'),
  ('fail_args', '--debug 4')],
 'post': [('post_enable', True), ('post_path', '/usr/bin/post_script.sh')],
 'pre': [('pre_enable', True),
  ('pre_path', '/usr/bin/pre_script.sh'),
  ('pre_args', '-la -w --dir')]}