在python中,按两个值按dict列表分组

在python中,按两个值按dict列表分组,python,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'} ] 为此: [ {

我正试图扭转这一局面:

[
  {'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 }}
]
最好的“蟒蛇式”方法是什么


itertools.groupby看起来一团糟,我不想为类似的事情加载像pandas这样沉重的包。

如果您的输入列表总是排序的,您应该只使用
itertools.groupby
;在您的示例输入列表中,就是这种情况,因此您可以执行以下操作:

另一种方法是使用字典,首先收集每个用户的权限,然后从该字典生成列表:

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()]
演示:


谢谢,您在第一个示例中缺少一个括号。另外,id丢失。基于您的答案构建,但将itemgetter替换为lambda来获取这两个值,从而得到了我想要的结果<代码>[{'perms':dict.fromkeys((p['perm']表示组中的p),True),'user':key[0],'id':key[1]}表示键,组中的组(inputlist,lambda t:(t['name'],t['id'])]@haki:无需使用
lambda
itemgetter()
可以处理多个键。
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'}]