Вы должны использовать только 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'}]
Спасибо, Ваш хватает скобки в первом примере. Кроме того, идентификатор отсутствует. – haki
Построенный на вас ответ, но заменивший itemgetter лямбдой, чтобы получить оба значения, дал мне результат, который я искал. '[{'perms': dict.fromkeys ((p ['perm'] для p в группе), True), 'user': key [0], 'id': key [1]} для клавиши, group in groupby (inputlist, lambda t: (t ['name'], t ['id']))] ' – haki
@haki: ах, я пропустил недостающий идентификатор, исправлен. –