在很多时候,我们需要找出多个列表或者集合对象的共同元素。比如,我们可能需要求出两个标准列表对象的共同元素,或者两个标准字典对象的key相同的元素,两个标准字典对象中key和value都相同的元素。
具体到实际的业务中,例如:我们用字典来表示一个班级中每个学生所有课程的成绩,并且每个学生所修的课程有差异。我们就可能面临需要找出两个学生都在学习的科目。
最快捷的方式是使用集合操作运算符来解决这个问题。
Python提供 '&', '|', '-' 和'^' ,即交、并、差和对称差集四种运算符。
例如,t, s 是两个集合,则这4种运算的含义为:
a = t | s # t 和 s的并集
b = t & s # t 和 s的交集
c = t – s # 求差集(项在t中,但不在s中)
d = t ^ s # 对称差集(项在t或s中,但不会同时出现在二者中)
回到我们的例子,假设学生a的成绩如下:
a = {
"数字电路":56,
"模拟电路":66,
"西方经济学":77,
"计算机英语":88
}
假设学生b的成绩如下:
b = {
"数字电路":56,
"模拟电路":66,
"政治经济学":78,
"计算机英语":89
}
1、如果要找出他们二人都学习的科目,则用针对key的交集运算即可得出
common_class = a.keys() & b.keys()
print('两人都学习的科目为:', common_class)
# 运行结果:两人都学习的科目为: {'模拟电路', '计算机英语', '数字电路'}
2、如果要找出他们二人中只被一个人学习的科目,则用针对key的对称差集运算即可得出
exclusive_class = a.keys() ^ b.keys()
print('只有一人的学习的科目', exclusive_class)
# 运行结果: 只有一人的学习的科目 {'政治经济学', '西方经济学'}
3、如果要找出所有的科目,则针对key做并集运算即可得出:
all_class = a.keys() | b.keys()
print('所有的科目', all_class )
# 运行结果: 所有的科目 {'模拟电路', '计算机英语', '数字电路', '政治经济学', '西方经济学'}
4、如果要找出学生a学习的科目,而b没有学习的科目,则针对key做差集运算即可得出:
only_class = a.keys() - b.keys()
print('a有学习而b未学习的科目', only_class )
# 运行结果: a有学习而b未学习的科目 {'西方经济学'}
从以上的例子我们可以看出,在Python里,字典的keys()运算生成的key集被视作一种集合对象。可以执行集合所具有的相关的运算。这几种运算是不适用于列表对象的,因为列表时允许重复的元素出现的,这点使得它是和集合完全不同的类型,所以Python在设计时就没必要让其支持这种运算。
接上面的例子里,进一步的,如果我们要找出两个字典中完全相同的元素,也可以借助于集合运算来实现。因为在字典对象中,像key一样,每个元素都是唯一的。
5、如果要找出他们二人都科目和成绩都一样条目,则用针对items的交集运算即可得出
common_class_score = a.items() & b.items()
print('两人成绩相同的共同科目为:', common_class_score)
# 运行结果:两人都成绩相同的共同科目为: {'模拟电路', '计算机英语', '数字电路'}
同理,我们可以对items()执行其他三种集合运算。
最后,字典的values(),即字典的值的集合(对字典执行values()运算得到的结果),是不支持集合运算的。作为一个小小的练习,请读者自己说明下为何Python没有支持字典对象values()的集合运算。