在很多时候,我们需要找出多个列表或者集合对象的共同元素。比如,我们可能需要求出两个标准列表对象的共同元素,或者两个标准字典对象的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()的集合运算。