在Python3中按相同的值对字典列表进行分组

在Python3中按相同的值对字典列表进行分组,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,给出字典列表: players= [ { "name": 'matt', 'school': 'WSU', 'homestate': 'CT', 'position': 'RB' }, { "name": 'jack', 'school': 'ASU', 'homestate': 'AL', 'position': 'QB' }, { "name": 'john', 'school': 'WSU', 'homestate': 'MD', 'position': 'LB' },

给出字典列表:

players= [
   { "name": 'matt', 'school': 'WSU', 'homestate': 'CT', 'position': 'RB' },
   { "name": 'jack', 'school': 'ASU', 'homestate': 'AL', 'position': 'QB' },
   { "name": 'john', 'school': 'WSU', 'homestate': 'MD', 'position': 'LB' },
   { "name": 'kevin', 'school': 'ALU', 'homestate': 'PA', 'position': 'LB' },
   { "name": 'brady', 'school': 'UM', 'homestate': 'CA', 'position': 'QB' },
]
我如何通过匹配匹配的字典值将它们分组,以使其输出:

匹配值1:

姓名:[马特、约翰、凯文]

学校:[WSU,WSU,ALU]

家乡:[加州、马里兰州、宾夕法尼亚州]

位置:[RB,磅,磅]

匹配值2:

姓名:[杰克,布雷迪]

学校:[华硕,嗯]

家乡:[加利福尼亚州艾尔]

职位:[QB,QB]

请注意,匹配值是任意的;也就是说,它随处可见。可能它在
学校
或者在
位置
,或者两者都在

我尝试通过以下方式对它们进行分组:

from collections import defaultdict

result_dictionary = {}

for i in players:
    for key, value in i.items():
        result_dictionary.setdefault(key, []).append(value)
它给出了:

{'name': ['matt', 'jack', 'john', 'kevin', 'brady'], 
 'school': ['WSU', 'ASU', 'WSU', 'ALU', 'UM'], 
 'homestate': ['CT', 'AL', 'MD', 'PA', 'CA'], 
 'position': ['RB', 'QB', 'LB', 'QB', 'QB']}

但我一直在思考如何进一步操作输出以匹配上面所述的所需输出,我相信有更好、更简单的方法可以做到这一点。

只需使用已导入的
集合。defaultdict

In [21]: from collections import defaultdict
    ...: result = defaultdict(lambda: defaultdict(list))
    ...: for d in players:
    ...:     for k,v in d.items():
    ...:         result[d['school']][k].append(v)
    ...:

In [22]: result
Out[22]:
defaultdict(<function __main__.<lambda>>,
            {'ASU': defaultdict(list,
                         {'homestate': ['AL'],
                          'name': ['jack'],
                          'position': ['QB'],
                          'school': ['ASU']}),
             'WSU': defaultdict(list,
                         {'homestate': ['CT', 'MD'],
                          'name': ['matt', 'john'],
                          'position': ['RB', 'LB'],
                          'school': ['WSU', 'WSU']})})
[21]中的
:从集合导入defaultdict
…:result=defaultdict(lambda:defaultdict(list))
…:对于d中的玩家:
…:对于k,v在d中。项()
…:结果[d['school'][k]。追加(v)
...:
在[22]中:结果
出[22]:
defaultdict(,
{'ASU':defaultdict(列表,
{'homestate':['AL'],
“姓名”:[“杰克”],
'位置':['QB'],
“学校”:[ASU']}),
“WSU”:defaultdict(列表,
{'homestate':['CT','MD'],
“姓名”:[“马特”、“约翰”],
'位置':['RB','LB'],
‘学校’:['WSU','WSU']})

您可以找到最常见的标题值,并使用后一个值作为进一步分组的焦点:

import itertools
players= [
  { "name": 'matt', 'school': 'WSU', 'homestate': 'CT', 'position': 'RB' },
  { "name": 'jack', 'school': 'ASU', 'homestate': 'AL', 'position': 'QB' },
  { "name": 'john', 'school': 'WSU', 'homestate': 'MD', 'position': 'LB' },
  { "name": 'kevin', 'school': 'ALU', 'homestate': 'PA', 'position': 'S' },
  { "name": 'brady', 'school': 'UM', 'homestate': 'CA', 'position': 'QB' },
]
headers = ['name', 'school', 'homestate', 'position'] 
final_header = [[a, max(b, key=lambda x:b.count(x))] for a, b in zip(headers, zip(*[[i[b] for b in headers] for i in players])) if len(set(b)) < len(b)]
d = [[list(b) for _, b in itertools.groupby(filter(lambda x:x[i] == c, players), key=lambda x:x[i])][0] for i, c in final_header]
last_results = {'pattern {}'.format(i):{d[0][0]:[j[-1] for j in d] for c, d in zip(headers, zip(*map(dict.items, h)))} for i, h in enumerate(d, start=1)}

如果你有选择的话,我建议你使用熊猫。你可以很容易地将“匹配值是任意的;也就是说,它可以在任何地方找到。可能是在学校里,也可能在位置上,或者两者都有。”这并不清楚。你能举例说明吗?@juanpa.arrivillaga我编辑了这个问题来澄清它。我不完全确定这里的规则是什么(如果马特和约翰上的是同一所学校,但马特和杰克打的是同一个位置怎么办?你有马特和约翰小组和马特和杰克小组吗?或者即使约翰和杰克没有任何共同点,也把他们分成一个小组?或者任意挑选一个让马特和他们在一起?或者不任意挑选(可能尝试最大化或最小化小组数量)或者…?如果这个问题的答案意味着不应该把球员放进某种等价的班级划分中:如果马特和约翰上同一所学校,也打同一个位置,会怎么样?有一个马特和约翰小组,或者两个,或者可以接受吗?如果,比方说,匹配值是任意的;也许可以在“家园”或“学校”中找到。你如何处理?YukaLangbuana访问适当的值?我不明白你的意思。我的错误,我编辑了问题以澄清我的问题。
{'pattern 2': 
  {'homestate': ['AL', 'CA'], 
  'school': ['ASU', 'UM'], 
  'name': ['jack', 'brady'], 
  'position': ['QB', 'QB']}, 

'pattern 1': 
    {'homestate': ['CT', 'MD'], 
    'school': ['WSU', 'WSU'], 
    'name': ['matt', 'john'], 
    'position': ['RB', 'LB']}
}