Python的内置itertools
模块实际上具有一个groupby
function,但是为此,必须首先对要分组的元素进行排序,以使要分组的元素在列表中是连续的:
from operator import itemgetter
sortkeyfn = itemgetter(1)
input = [('11013331', 'KAT'), ('9085267', 'NOT'), ('5238761', 'ETH'),
('5349618', 'ETH'), ('11788544', 'NOT'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('9843236', 'KAT'), ('5594916', 'ETH'), ('1550003', 'ETH')]
input.sort(key=sortkeyfn)
现在输入看起来像:
[('5238761', 'ETH'), ('5349618', 'ETH'), ('962142', 'ETH'), ('7795297', 'ETH'),
('7341464', 'ETH'), ('5594916', 'ETH'), ('1550003', 'ETH'), ('11013331', 'KAT'),
('9843236', 'KAT'), ('9085267', 'NOT'), ('11788544', 'NOT')]
groupby
返回格式为的2元组序列(key, values_iterator)
。我们想要的是将其转换为字典列表,其中“类型”是键,而“项目”是values_iterator返回的元组的第0个元素的列表。像这样:
from itertools import groupby
result = []
for key,valuesiter in groupby(input, key=sortkeyfn):
result.append(dict(type=key, items=list(v[0] for v in valuesiter)))
现在result
包含您想要的字典,如您的问题所述。
但是,您可能会考虑仅对此做出一个单独的dict,按类型键入,每个值都包含值列表。在当前形式中,要查找特定类型的值,必须遍历列表以查找包含匹配的“ type”键的字典,然后从中获取“ items”元素。如果您使用单个词典而不是一个1项词典的列表,则可以通过在主词典中进行单键查找来查找特定类型的项目。使用groupby
,这看起来像:
result = {}
for key,valuesiter in groupby(input, key=sortkeyfn):
result[key] = list(v[0] for v in valuesiter)
result
现在包含此字典(这类似于res
@KennyTM答案中的中间defaultdict):
{'NOT': ['9085267', '11788544'],
'ETH': ['5238761', '5349618', '962142', '7795297', '7341464', '5594916', '1550003'],
'KAT': ['11013331', '9843236']}
(如果您希望将其减少为单层,则可以:
result = dict((key,list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn))
或使用新奇的dict-comprehension形式:
result = {key:list(v[0] for v in valuesiter)
for key,valuesiter in groupby(input, key=sortkeyfn)}
[('11013331', 'red', 'KAT'), ('9085267', 'blue' 'KAT')]
其中元组的最后一个元素是键,前两个是值。结果应该像这样:result = [{type:'KAT',items:[('11013331',red),('9085267',blue)]}]