我有以下简单的数据结构:
teams = [ { 'league_id': 1, 'name': 'Kings' }, { 'league_id': 1, 'name': 'Sharkls' }, { 'league_id': 2, 'name': 'Reign' }, { 'league_id': 2, 'name': 'Heat' } ]
leagues = [ { 'league_id': 1, 'name': 'League 1' }, { 'league_id': 2, 'name': 'League 2' } ]
我有以下dict
理解:
league_teams = { x['league_id']: [ t['name']
for t in teams if t['league_id'] == x ['league_id'] ]
for x in leagues }
哪个收益率:
{1: ['Kings', 'Sharkls'], 2: ['Reign', 'Heat']}
是否有更简单的方法使用itertools
或其他东西来获取该字典?这感觉有点麻烦。
答案 0 :(得分:1)
此处您不需要itertools
,而collections.defaultdict
是更好的选择。您的解决方案的复杂性是O(n * m),而defaultdict
,它将是O(n + m)。
你可以达到你想要的效果:
from collections import defaultdict
# create set to store `league_id` in `leagues`. Set holds unique
# values and also searching in set is faster than in normal list
leagues_id = set([item['league_id'] for item in leagues])
my_dict = defaultdict(list)
for item in teams:
if item['league_id'] in leagues_id:
my_dict[item['league_id']].append(item['name'])
最后my_dict
将保留值:
{1: ['Kings', 'Sharkls'], 2: ['Reign', 'Heat']}
修改:如果您还希望在my_dict
中输入联盟中的league_id
,而不是团队,则需要明确地输入以下内容:
for leagues_id in leagues_ids:
_ = my_dict[leagues_id] # Will create empty list for such ids
答案 1 :(得分:0)
检查t['league_id'] == x['league_id']
看起来没必要。
您可以简化:
import collections
league_teams = collections.defaultdict(list)
for t in teams:
league_teams[t['league_id']].append(t['name'])
如果你真的想要itertools
:
import itertools
league_teams = {k: [t['name'] for t in g]
for k, g in itertools.groupby(teams, key=lambda t: t['league_id'])}
但只有在球队列表排序后才会有效。
答案 2 :(得分:0)
这是Moinuddin Quadri的O(n + m)解决方案的改编版,该解决方案能够抓住空联盟#34;大小写,顺便说一下,不需要导入任何模块。 dict output
作为league_ids
集合执行双重任务,并且由于它已预先初始化,因此不需要collections.defaultdict
:
output = { league['league_id']:[] for league in leagues }
for team in teams:
if team['league_id'] in output:
output[team['league_id']].append(team['name'])
print(output)
输出结果为:
{1: ['Kings', 'Sharkls'], 2: ['Reign', 'Heat']}