Python实例:字典共同键值查找的两种实现方法

一、实际场景

比如,NBA每场球星的得分统计,都以字典格式存储:
第一场:{'詹姆斯': 32, '库里': 22, '字母哥': 18, ...}
第二场:{'詹姆斯': 23, '恩比德': 17, '杜兰特': 28, ...}
第三场:{'詹姆斯': 27, '哈登': 19, '利拉德': 16, ...}

下面我们需要统计出前N场比赛,每场进球都在20分以上的球员。
其实,上面的场景就是在N个字典中寻找公共键值的问题,这里给出两种解决方案。

二、字典共同键值查找的实现方法

2.1 直观的解决方法

为了解决这个问题,我们首先假设只有3场比赛,则解决上面问题的步骤为:

  • 1、使用randint方法简便的设计3场比赛和每个球员每场比赛进球的字典数据;
  • 2、使用filter函数对每场比赛进行球员得分筛选,剔除每场比赛小于20分的球员;
  • 3、对于比赛场数比较少的时候,可以考虑直接使用列表解析方法,得到在这三场比赛中,得分都在20分以上的球员。
from random import randint

# 球员列表:
player_list = ['詹姆斯', '库里', '字母哥', '恩比德', '杜兰特', 
				'哈登', '利拉德', '戴维斯', '乔治']

# 1.构造3场比赛每个球员的进球数
round_1 = {player: randint(0, 32) for player in player_list}
round_2 = {player: randint(0, 32) for player in player_list}
round_3 = {player: randint(0, 32) for player in player_list}

# 2.筛选3场比赛球员进球字典中进球数大与20的球员
round_1_filter = dict(filter(lambda x: x[1] >= 20, round_1.items()))
round_2_filter = dict(filter(lambda x: x[1] >= 20, round_2.items()))
round_3_filter = dict(filter(lambda x: x[1] >= 20, round_3.items()))

# 3.使用列表解析分析在这三场比赛中,得分都在20分以上的球员:
player_with_20score = [player for player in round_1_filter
		if (player in round_2_filter) and (player in round_3_filter)]

# 4.输出三场比赛得分均在20分以上的球员
print('三场比赛得分均在20分以上的球员:', player_with_20score)

上述解决方法对于比赛场数表少时还可以考虑使用。假如,要统计一个赛季每场比赛都在15分以上的球员呢?我们总不能手动的一个个输入吧;或者我们在得到数据之前并不知道要统计多少个场次的比赛。所以,下面设计一个更加通用的解决方法。

2.2 更为通用的解决方法

更为通用的解决方案步骤如下所示:

  • 1、首先通过字典解析的嵌套应用,构造一个嵌套字典格式的随机场次为N的比赛,且以字典形式存储对应场次的比赛中每个球员的得分情况的字典round_dict,字典数据格式如下所示:

在这里插入图片描述

  • 2、对round_dict字典进行键值和值的遍历,并使用filter函数结合匿名函数lambdaround_dict字典中得分在15分以上的球员进行筛选,得到只包含每场比赛得分在15分以上的数据字典round_dict_filterround_dict_filter字典中的数据内容如下图所示:

在这里插入图片描述

  • 3、由于字典不支持通过[x]角标读取数据,所以先将筛选后的字典round_dict_filter中的值(不用转换键值)转换为只包含球员得分数据的字典列表round_value_list,其数据格式如下所示:

在这里插入图片描述
为了找出round_dict_filter中每场比赛得分均在15分以上的球员,可以使用如下的列表解析方法,并配合匿名函数lambdamap函数实现:

players_15_score = [player for player in round_value_list[0] 
			if all(map(lambda x: player in x, round_value_list[1:]))]

上面代码中的player for player in round_value_list[0]指令首先将第一场比赛的球员的键值变为可迭代对象player,然后使用lambda匿名函数将除了第一场比赛外的其余场次中的球员变为可迭代对象,并通过指令all(map(lambda x: player in x, round_value_list[1:]))判断第一场的球员是否在剩余所有的场次中。

from random import randint

# 球员列表:
player_list = ['詹姆斯', '库里', '字母哥', '恩比德', '杜兰特', 
				'哈登', '利拉德', '戴维斯', '乔治', '米切尔', '英格拉姆',
				'拉文', '唐斯', '巴特勒']

# 1.使用字典嵌套解析生成字典数据数据:
# 下面的代码生成一个5-15随机比赛场数,
# 每场每个球员得分在8-40之间的字典数据
round_dict = {'round_%d' % i: {player: randint(8, 40) 
		for player in player_list} 
		for i in range(randint(5, 15))}

# 2.下面的代码是直接针对字典进行数据筛选操作的,操作的结果为:
# (1) 开辟一个新的字典空间用于存储筛选后的数据:
round_dict_filter = {}

# (2) 将每场比赛中球员得分在15分以上的数据留下,
# 并存储于round_dict_filter字典。
for key, value in round_dict.items():
	round_dict_filter[key] = dict(filter(
			lambda x: x[1] >= 15, value.items()))

# 3.使用列表解析分析在N场比赛中,得分都在15分以上的球员:
# (1) 首先将以字典格式存储的每场比赛每个球员的得分转换为
# 列表形式
round_value_list = list(round_dict_filter.values())

# (2) 筛选每场都在15分以上的球员
players_15_score = [player for player in round_value_list[0] 
			if all(map(lambda x: player in x, round_value_list[1:]))]

# 4.输出三场比赛得分均在15分以上的球员
print('三场比赛得分均在15分以上的球员:', players_15_score)
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值