[英]Combining identical values against a list of dictionaries in Python
我正在使用python构建表。 该表的行包含在词典列表中,如下所示:
table = [{ 'User' : 'johndoe', 'Profile' : 'Production', 'Risk' : 'No MFA', 'Action': 'Disable account and notify user' },
{ 'User' : 'janedoe', 'Profile' : 'Production', 'Risk' : 'Expired Password', 'Action': 'Reset password and notify user' },
{ 'User' : 'cookiedoe', 'Profile' : 'Non-Production', 'Risk' : 'Expired key', 'Action': 'Delete old key and notify user' },]
每当我检测到不符合条件时,我都会运行一个函数来构建行。 我的目标是合并“用户”和“个人资料”相同的行。 例如,如果Production中的johndoe也有过期的密码,那么我希望他的字典看起来像这样:
{ 'User' : 'johndoe', 'Profile' : 'Production', 'Risk' : 'No MFA, Expired password', Action: 'Disable account and notify user\n Reset password and notify user' }
当前的每一行都生活在称为“行”的本地词典中。 这就是我现在想要实现的方式:
for past_row in table:
past_user = past_row['User']
row_user = row['User']
past_profile = past_row['Profile']
row_profile = row['Profile']
if past_user == row_user and past_profile == row_profile:
past_row['Risk'] = "%s, %s" %(past_row['Risk'], row['Risk'])
past_row['Action'] = "%s\n %s" %(past_row['Action'], row['Action'])
我的Python脚本无休止地运行,没有完成。 我感觉自己在低效率地检查过去的行,而且我还很年轻,接受过Python语言教育。 围着谷歌搜索只是让我的逻辑更加混乱。 有人可以让我挺直吗?
好的,我想出了一个快速的解决方案。 它可以更高效地完成,但是,请记住您是Python的初学者,我将重点放在可读性上。 它就到了(脚本可以按原样执行):
# Import default-dictionary.
from collections import defaultdict
# Minimal sample, we want to merge johndoe.
table = [{ 'User' : 'johndoe', 'Profile' : 'Production', 'Risk' : 'No MFA', 'Action': 'Disable account and notify user' },
{ 'User' : 'johndoe', 'Profile' : 'Production', 'Risk' : 'Expired Password', 'Action': 'Reset password and notify user' },
{ 'User' : 'cookiedoe', 'Profile' : 'Non-Production', 'Risk' : 'Expired key', 'Action': 'Delete old key and notify user' },]
# Inline function definition for combinining risks/actions
# from multiple profiles.
combine_risks = lambda ps: ', '.join([p['Risk'] for p in ps])
combine_actions = lambda ps: ', '.join([p['Action'] for p in ps])
# Merge multiple profile dicts into one.
def combine_profiles(profiles):
return dict(
User=profiles[0]['User'],
Profile=profiles[0]['Profile'],
Risk=combine_risks(profiles),
Action=combine_actions(profiles)
)
# Profile - indices mapping.
prof2ind = defaultdict(set)
# Enumerate profiles and save information about which profiles
# have matching User and Profile.
for index, row in enumerate(table):
key = (row['User'], row['Profile'])
prof2ind[key].add(index)
new_table = []
# Finally, build merged table.
# 'indices' is a set holding indices of matching profile-sets.
for indices in prof2ind.values():
profiles = [table[i] for i in indices]
new_table.append(combine_profiles(profiles))
# Check the result.
print(new_table)
从某种意义上说,此脚本是通用的,可用于多个匹配的配置文件,而不仅仅是对。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.