[英]Group by a list of dicts by two values in python
我试图把这个:
[
{'perm':'copy', 'id':1, 'name':'user1'},
{'perm':'read', 'id':1, 'name':'user1'},
{'perm':'delete', 'id':2, 'name':'user2'},
{'perm':'copy', 'id':2, 'name':'user2'},
{'perm':'update', 'id':3, 'name':'user3'}
]
到这个:
[
{'id':1, 'name':'user1', 'perms': {'copy': True, 'read': True}}
{'id':2, 'name':'user2', 'perms': {'copy': True, 'delete': True}}
{'id':3, 'name':'user3', 'perms': {'update': True }}
]
最好的“ pythonic”方法是什么?
itertools.groupby看起来一团糟,我不想为类似的东西加载像熊猫这样的笨重的包裹。
仅当输入列表始终排序时,才应使用itertools.groupby
; 在示例输入列表中,就是这种情况,因此您可以执行以下操作:
from operator import itemgetter
from itertools import groupby
[{'perms': dict.fromkeys((p['perm'] for p in group), True), 'id': key[0], 'user': key[1]}
for key, group in groupby(inputlist, itemgetter('id', 'name'))]
使用的另一种方法是字典,该字典首先收集每个用户的权限,然后从该字典生成列表:
per_user = {}
for perm in inputlist:
key = perm['id'], perm['name']
per_user.setdefault(key, {})[perm['perm']] = True
[{'perms': value, 'id': key[0], 'user': key[1]} for key, value in per_user.iteritems()]
演示:
>>> from operator import itemgetter
>>> from itertools import groupby
>>> from pprint import pprint
>>> inputlist = [
... {'perm':'copy', 'id':1, 'name':'user1'},
... {'perm':'read', 'id':1, 'name':'user1'},
... {'perm':'delete', 'id':2, 'name':'user2'},
... {'perm':'copy', 'id':2, 'name':'user2'},
... {'perm':'update', 'id':3, 'name':'user3'}
... ]
>>> [{'perms': dict.fromkeys((p['perm'] for p in group), True), 'id': key[0], 'user': key[1]}
... for key, group in groupby(inputlist, itemgetter('id', 'name'))]
[{'perms': {'read': True, 'copy': True}, 'id': 1, 'user': 'user1'}, {'perms': {'copy': True, 'delete': True}, 'id': 2, 'user': 'user2'}, {'perms': {'update': True}, 'id': 3, 'user': 'user3'}]
>>> pprint(_)
[{'id': 1, 'perms': {'copy': True, 'read': True}, 'user': 'user1'},
{'id': 2, 'perms': {'copy': True, 'delete': True}, 'user': 'user2'},
{'id': 3, 'perms': {'update': True}, 'user': 'user3'}]
>>> per_user = {}
>>> for perm in inputlist:
... key = perm['id'], perm['name']
... per_user.setdefault(key, {})[perm['perm']] = True
...
>>> [{'perms': value, 'id': key[0], 'user': key[1]} for key, value in per_user.iteritems()]
[{'perms': {'update': True}, 'id': 3, 'user': 'user3'}, {'perms': {'copy': True, 'delete': True}, 'id': 2, 'user': 'user2'}, {'perms': {'read': True, 'copy': True}, 'id': 1, 'user': 'user1'}]
>>> pprint(_)
[{'id': 3, 'perms': {'update': True}, 'user': 'user3'},
{'id': 2, 'perms': {'copy': True, 'delete': True}, 'user': 'user2'},
{'id': 1, 'perms': {'copy': True, 'read': True}, 'user': 'user1'}]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.