1.5 快速找到多个字典中的公共键

实际场景

2022 年,中国队踢进了世界杯,以下是中国队每轮球员的进球统计:

  • 第一轮:{'Airing': 7, '刘杰容': 2, '梁志豪': 1, '王国全': 3 ...}
  • 第二轮:{'Airing': 4, '王国全': 1, '墨夏': 2, '向晓宇': 1 ...}
  • 第三轮:{'Airing': 9, '梁志豪': 2, '向晓宇': 1, '王国全': 3 ...}
  • ...

现在问题来了,若评出最佳球员,需要统计出前 N 轮每场比赛都有进球的球员,应该如何实现?

常规解法:迭代

from random import randint, sample

# 假设一共只有 7 名球员,随机取样出 3~6 个球员进球
# 字典解析产生每轮的数据
s1 = {x: randint(1, 4) for x in sample('abcdefg', randint(3, 6))}
s2 = {x: randint(1, 4) for x in sample('abcdefg', randint(3, 6))}
s3 = {x: randint(1, 4) for x in sample('abcdefg', randint(3, 6))}

res = []
for k in s1: 
    for k in s2 and k in s3:
        res.append(key)

print(res)

但是这种方法相对啰嗦,而且效率不够好? 那是否有更优雅的解法呢?

利用集合的交集操作

这里我们可以利用集合来简化我们的代码。

from random import randint, sample

# 假设一共只有 7 名球员,随机取样出 3~6 个球员进球
# 字典解析产生每轮的数据
s1 = {x: randint(1, 4) for x in sample('abcdefg', randint(3, 6))}
s2 = {x: randint(1, 4) for x in sample('abcdefg', randint(3, 6))}
s3 = {x: randint(1, 4) for x in sample('abcdefg', randint(3, 6))}

print(s1.viewkeys() & s2.viewkeys() & s3.viewkeys())

map - reduce

一行代码就解决了问题,是不是很优雅? 那如果不止 3 轮呢?又该如何解决?

那就需要用到 map - reduce 了。

具体步骤如下:

  1. 使用字段的viewkeys()方法,得到一个字典keys的集合
  2. 使用map函数,得到所有字典keys的集合
  3. 使用reduce函数,取所有字典的keys的集合的交集
from random import randint, sample

# 假设一共只有 7 名球员,随机取样出 3~6 个球员进球
# 字典解析产生每轮的数据
s1 = {x: randint(1, 4) for x in sample('abcdefg', randint(3, 6))}
s2 = {x: randint(1, 4) for x in sample('abcdefg', randint(3, 6))}
s3 = {x: randint(1, 4) for x in sample('abcdefg', randint(3, 6))}

reduce(lambda a, b: a & b, map(dict.viewkeys, [s1, s2, s3]))

恩,同样也是一条命令解决,更加优雅。

results matching ""

    No results matching ""