Python:在键相同的字典列表中组合唯一值?

Syn*_*DEV 6 python list python-3.x dictionary-comprehension

我不确定我是否以正确的方式提问,但这是我的问题:

我有以下格式的字典列表:

[
{'user': 'joe', 'IndexUsed': 'a'}, 
{'user': 'joe', 'IndexUsed': 'a'},
{'user': 'joe', 'IndexUsed': 'a'},
{'user': 'joe', 'IndexUsed': 'b'}, 
{'user': 'admin', 'IndexUsed': 'a'}, 
{'user': 'admin', 'IndexUsed': 'c'},
{'user': 'hugo', 'IndexUsed': 'a'},
{'user': 'hugo', 'IndexUsed': 'd'},
...
]
Run Code Online (Sandbox Code Playgroud)

我希望我的最终结果如下所示:

[
{'user': 'joe', 'IndexUsed': ['a', 'b']}, 
{'user': 'admin', 'IndexUsed': ['a', 'c']}, 
{'user': 'hugo', 'IndexUsed': ['a', 'd']},
]
Run Code Online (Sandbox Code Playgroud)

从本质上讲,合并/重复删除中的唯一字段IndexUsed并将它们减少到每个字典只有一个user

我已经研究过使用减速器、字典理解并在 StackOverflow 上进行搜索,但是我在使用字符串查找用例时遇到了一些麻烦。我发现的大多数示例都使用整数将它们组合成最终的 int/float,但在这里我更愿意将它组合成一个最终的字符串。你能帮我理解如何解决这个问题吗?

use*_*432 1

如果保证字典按名称分组在一起,那么您可以使用itertools.groupby单独处理每组字典:

from itertools import groupby
from operator import itemgetter

data = [
    {'user': 'joe', 'IndexUsed': 'a'},
    {'user': 'joe', 'IndexUsed': 'a'},
    {'user': 'joe', 'IndexUsed': 'a'},
    {'user': 'joe', 'IndexUsed': 'b'},
    {'user': 'admin', 'IndexUsed': 'a'},
    {'user': 'admin', 'IndexUsed': 'c'},
    {'user': 'hugo', 'IndexUsed': 'a'},
    {'user': 'hugo', 'IndexUsed': 'd'},
]

merged_data = [{"user": key, "IndexUsed": list({i: None for i in map(itemgetter("IndexUsed"), group)})} for key, group in groupby(data, key=itemgetter("user"))]
for d in merged_data:
    print(d)
Run Code Online (Sandbox Code Playgroud)

输出:

{'user': 'joe', 'IndexUsed': ['a', 'b']}
{'user': 'admin', 'IndexUsed': ['a', 'c']}
{'user': 'hugo', 'IndexUsed': ['a', 'd']}
>>> 
Run Code Online (Sandbox Code Playgroud)

这只是我想到的第一件事,但出于多种原因我不喜欢它。首先,就像我说的,它假设原始字典通过 key 分组在一起user。此外,长列表推导式不可读,应避免。生成合并列表的方式IndexUsed是创建一个临时字典,将唯一条目映射到None(呃,粗略 - 使用字典而不是集合,因为集合不保留插入顺序)。它还假设您使用的是 Python 3.x+ 的某个版本,其中字典保证保留插入顺序(您可以使用 更明确collections.OrderedDict,但这又是一个导入)。最后,您不必对"user""IndexUsed"key-literals 进行硬编码。有人请提出更好的答案。