今天你 AI 赋能了吗?打开浏览器,在地址栏输入 xuefulu.ai ,按下 Enter 即可访问学府路1号!
2026年10月14日 星期三 10:40:21
常用网址: | | 学府路1号 https://xuefulu.ai | 下载 Python https://xuefulu.ai/Python.html | 下载 TRAE https://xuefulu.ai/Trae.html

一、为什么需要集合

列表能装一串东西、能重复、按位置找;字典能按名字找值。但有一类需求这两个都不顺手:「这里面的东西不能重复」和「某某在不在里面」。

比如一份报名名单,同一个名字被填了两遍,要数一数到底有几个人报名:

Python
names = ['小明', '小红', '小明', '小刚', '小红']
print('名单条数:', len(names))
print('实际人数:', len(set(names)))

输出:

输出
名单条数: 5
实际人数: 3

用 set() 一包,重复的自动就没了。这就是集合:一袋不许重复的东西,它的长项是「去重」和「判断在不在」,而不是「排第几」。

容器一句话最擅长
列表 []一队有顺序的人按位置取、要顺序、允许重复
元组 ()刻在石头上的名单内容不许改
字典 {}一本词典按名字(键)查值
集合 set()一袋不许重复的东西去重、判断在不在、做交并差
记住一句话就行:要顺序用列表,要对应关系用字典,要去重和「有没有」用集合。

课程思政|数据安全与法治素养 · 名单里每个名字都是人

集合的第一本事是去重:一份报名名单,用 set() 一包,重复的名字自动只剩一个。可别弄反了——被去掉的只是重复的登记,不等于这个人可以随便被抹掉。数据能合并、能去重,但每条记录背后都是活生生的人。以后再收集学号、手机号这类信息,多问一句该不该留、能留多久,是统计人该有的分寸。

二、创建集合的四种方式

方式一:花括号里直接写

和字典一样用花括号,但里面只有元素、没有冒号。

Python
fruits = {'苹果', '香蕉', '龙眼'}
print(len(fruits))
print('苹果' in fruits)

输出:

输出
3
True

方式二:用 set() 把别的序列变过来(顺手去重)

Python
print(set([1, 2, 2, 3, 3, 3]))
print(sorted(set('hello')))

输出:

输出
{1, 2, 3}
['e', 'h', 'l', 'o']

set() 能吃掉列表、字符串、元组、range 等任何「能一个个数出来」的东西。字符串会被拆成一个一个字符。

方式三:空集合只能写 set()

这是集合最大的一个坑:{} 是空字典,不是空集合。

Python
s = {}
s.add(1)

运行后会报错(逐字照抄解释器):

报错
AttributeError: 'dict' object has no attribute 'add'

括号里什么都没有时,Python 默认建的是字典。想要空集合,必须写 set():

Python
s = set()
s.add(1)
print(s)
print(type(s))

输出:

输出
{1}
<class 'set'>

方式四:集合推导式(先看个样子)

Python
print({x * x for x in range(1, 6)})

输出:

输出
{1, 4, 9, 16, 25}

写法像列表推导式,只是外面换成花括号。它天生就会去重,第八节细讲。

写法结果备注
{1, 2, 3}含 3 个元素的集合最常用
set([1, 2, 2]){1, 2}从别的序列转过来,顺手去重
set()空集合只能用这一种!
{}空字典别搞错
{x for x in range(3)}{0, 1, 2}集合推导式
最常见的新手错误:想建空集合写了 {}。它是个空字典,后面一调用集合的方法(比如 add)就报 AttributeError: 'dict' object has no attribute 'add'。请记牢:空集合写 set()。

三、集合的三条规矩(不重复、无序、元素不可变)

规矩 1:不重复,重复的自动被吃掉

Python
s = {1, 2, 2, 3, 3, 3}
print(s)
print(len(s))

输出:

输出
{1, 2, 3}
3

规矩 2:无序——不能用下标,也不能切片

集合不记「谁排第几」,所以 s[0] 这种写法直接报错。

Python
s = {1, 2, 3}
print(s[0])

运行后会报错(逐字照抄解释器):

报错
TypeError: 'set' object is not subscriptable

两个后果要记住:

  1. 想「按顺序取第几个」,请改用列表。
  2. print(s) 出来的顺序不保证和你写进去的顺序一样(元素越多、越不是小数字,越容易看出来)。想让输出每次都固定,先 sorted()。
Python
s = {3, 1, 2}
print(sorted(s))
print(sorted(s, reverse=True))

输出:

输出
[1, 2, 3]
[3, 2, 1]

顺带记一句:集合比的是「内容一样不一样」,跟顺序无关。

Python
print({1, 2, 3} == {3, 2, 1})

输出:

输出
True

规矩 3:元素必须「不可变」

集合内部要靠一个「位置」来快速找到元素,所以元素必须是算得出固定位置的东西(术语叫「可哈希」)。列表和字典会变,放不进去。

Python
s = {[1, 2], 3}

运行后会报错(逐字照抄解释器):

报错
TypeError: unhashable type: 'list'

能放的:数字、字符串、True/False、元组(前提是元组里装的也都是不可变的)。

Python
s = {(1, 2), (3, 4)}
print(sorted(s))

输出:

输出
[(1, 2), (3, 4)]
元素类型能不能放进集合为什么
数字 10能不可变
字符串 'abc'能不可变
元组 (1, 2)能(里面也得都是不可变的)元组本身不可变
列表 [1, 2]不能会变,报 unhashable
字典 {'a': 1}不能会变
集合 {1, 2}不能普通集合会变(frozenset 才行)

四、往里加、往外删(add / update / remove / discard / pop / clear)

集合的增删方法不多,记住下面六张「面孔」就够了。

方法作用要不要给值
s.add(x)加一个元素给
s.update(序列)一次加一批给
s.remove(x)删掉 x,没有就报错给
s.discard(x)删掉 x,没有也不报错给
s.pop()随便删掉一个并返回它不给
s.clear()全部清空不给

add:加一个(重复加等于没加)

Python
s = {1, 2, 3}
s.add(4)
print(sorted(s))
s.add(4)          # 已经有了,加了也白加
print(len(s))     # 还是 4 个

输出:

输出
[1, 2, 3, 4]
4

注意 add() 自己不返回值,别写 s = s.add(4)——那样 s 会变成 None。

update:一次加一批

Python
s = {1, 2}
s.update([3, 4, 4, 5])
print(sorted(s))

输出:

输出
[1, 2, 3, 4, 5]

remove 和 discard:删一个

差别只有一个:删不存在的元素时,remove 报错,discard 当没事发生。

Python
s = {1, 2, 3}
s.remove(99)

运行后会报错(逐字照抄解释器):

报错
KeyError: 99

不确定在不在,就用 discard;确定在、想让它报错帮你查问题,就用 remove。

Python
s = {1, 2, 3}
s.discard(99)     # 没有,也不报错
s.remove(1)       # 有,正常删掉
print(sorted(s))

输出:

输出
[2, 3]

pop:随便删掉一个(不能指定删谁)

Python
s = {10, 20, 30}
print(s.pop())
print(sorted(s))

输出:

输出
10
[20, 30]

因为集合无序,「第一个」没有意义,所以 pop() 删的是随便哪个,只适合「我随便拿一个出来处理」的场景。

clear:清空

Python
s = {1, 2, 3}
s.clear()
print(s)
print(bool(s))    # 空集合在判断里算「假」

输出:

Python
set()
False

五、遍历与判断(for、in、len)

一个个过一遍:for

集合也能 for。因为无序,想要固定顺序就先 sorted()。

Python
for x in sorted({3, 1, 2}):
    print(x)

输出:

输出
1
2
3

判断「在不在」:in(集合的看家本领)

Python
s = {1, 2, 3}
print(2 in s)
print(9 in s)
print(9 not in s)

输出:

输出
True
False
True
为什么集合的 in 特别快?列表要从头一个一个比,集合能直接算出它该在的位置去看一眼。所以「一长串数据里反复判断某个东西在不在」时,先把它们装进集合,速度会差很多。

数个数、找最大最小、求和

和列表一样,这些内置函数集合都能用:

Python
s = {5, 1, 9}
print(len(s), max(s), min(s), sum(s))

输出:

输出
3 9 1 15

六、四个集合运算(交集 &、并集 |、差集 -、对称差 ^)

集合最漂亮的用法,是「拿两个集合比一比」。四个符号,对应四种关系:

符号名字含义生活里的样子
&交集两边都有的两个班都报名的同学
|并集两边合起来全部(自动去重)两个班加起来的所有人
-差集在左边、不在右边的只在 A 班、没去 B 班的人
^对称差只出现在一边的(去掉共同部分)只在一个班出现过的人
Python
a = {1, 2, 3}
b = {2, 3, 4}
print('交集:', a & b)
print('并集:', a | b)
print('差集 a-b:', a - b)
print('差集 b-a:', b - a)
print('对称差:', a ^ b)

输出:

输出
交集: {2, 3}
并集: {1, 2, 3, 4}
差集 a-b: {1}
差集 b-a: {4}
对称差: {1, 4}
差集有方向!a - b 是「在 a 里但不在 b 里」,b - a 正好相反。写的时候先在心里念一遍「谁减谁」。

换成人名,就是一道很常见的题:

Python
class_a = {'小明', '小红', '小刚'}
class_b = {'小红', '小刚', '小美'}
print('两个班都有的:', sorted(class_a & class_b))
print('两个班全部的人:', sorted(class_a | class_b))
print('只在 A 班的:', sorted(class_a - class_b))
print('只在一个班的:', sorted(class_a ^ class_b))

输出:

输出
两个班都有的: ['小刚', '小红']
两个班全部的人: ['小刚', '小明', '小红', '小美']
只在 A 班的: ['小明']
只在一个班的: ['小明', '小美']

再来看两份书单,想知道哪些书重复买了、哪些只买了一边:

Python
list1 = {'西游记', '水浒传', '朝花夕拾'}
list2 = {'红楼梦', '西游记', '呐喊'}
print('重复买的:', sorted(list1 & list2))
print('只买了没重复的:', sorted(list1 ^ list2))

输出:

输出
重复买的: ['西游记']
只买了没重复的: ['呐喊', '朝花夕拾', '水浒传', '红楼梦']
中文用 sorted() 排出来是按字符编码排的,不是按拼音,所以顺序看着可能有点怪,这不是错。

课程思政|诚信与职业操守 · 交集是共识,差集是盲区

交集 & 挑出两边都有的,差集 - 挑出只在一侧的。别只顾着看交集里「我们都同意的那批人」,做工作更要盯紧差集:只出现在一边的记录,往往才是问题藏身的地方。团队做数据核对也是这样,两个人口径一对,能对上的先放一放,对不上的逐条查——差异不是麻烦,它是线索。

七、方法版(intersection / union / difference / issubset…)

同样四件事,换成方法写

四个运算符都有一个同名的方法:

Python
a = {1, 2, 3}
print(a.intersection([2, 3, 4]))
print(a.union([4]))
print(a.difference([2]))
print(a.symmetric_difference([3, 4]))

输出:

输出
{2, 3}
{1, 2, 3, 4}
{1, 3}
{1, 2, 4}

结果是 {2, 3}、{1, 2, 3, 4}、{1, 3}、{1, 2, 4},和用符号一模一样。

运算符号写法方法写法
交集a & ba.intersection(b)
并集a | ba.union(b)
差集a - ba.difference(b)
对称差a ^ ba.symmetric_difference(b)
两者有个关键区别:符号两边必须都是集合,方法可以吃列表。{1, 2, 3} & [2, 3] 会报 TypeError,而 {1, 2, 3}.intersection([2, 3]) 是好的。数据本来就在列表里、又不想先转成集合时,用方法更省事。
Python
print({1, 2, 3} & [2, 3])

运行后会报错(逐字照抄解释器):

报错
TypeError: unsupported operand type(s) for &: 'set' and 'list'

三个判断题

这三个返回的都是 True / False,用来问「集合之间是什么关系」。

Python
a = {1, 2}
print(a.issubset({1, 2, 3}))      # a 是它的子集吗(a 全在里面)
print({1, 2, 3}.issuperset(a))    # 它把 a 全包含了吗
print(a.isdisjoint({4, 5}))       # 两边完全没有重复吗

输出:

输出
True
True
True

子集也能用比较符号写,但这里有个大坑:

Python
print({1, 2} <= {1, 2, 3})    # True:是子集
print({1, 2} < {1, 2})       # False:小于等于成立,但不「小于」

输出:

输出
True
False
集合里的 <= 不是「小于等于」,是「子集」;< 是「真子集」(少一个才算)。看到集合比较大小别想成数字,{1, 2} < {1, 2} 是 False 而不是 True,正是这个道理。

AI 助手小贴士|四个集合运算符用「班级名单」一讲就懂。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:|、&、-、^ 四个集合运算符各是什么意思?用「1 班和 2 班名单」的例子各演示一遍,打印结果并解释

八、集合推导式

和列表推导式长得几乎一样,只是把方括号换成花括号。得到的结果是一个集合,所以天生去重。

Python
print({x * x for x in range(1, 6)})
print(sorted({x for x in range(10) if x % 3 == 0}))

输出:

输出
{1, 4, 9, 16, 25}
[0, 3, 6, 9]

把「每个元素的第一个字母」收集起来,重复的自动只留一个:

Python
words = ['apple', 'banana', 'avocado']
print(sorted({w[0] for w in words}))

输出:

输出
['a', 'b']
集合是无序的,字符串集合打印出来的顺序每次运行都可能不一样,所以这里先 sorted() 排一下。自己调试时看到顺序变了,不是程序出错。
推导式 + 集合 = 一句话完成「挑出来 + 去重」。比如 {n % 10 for n in nums} 就是「所有数字的个位数有哪几种」。

九、frozenset:不可变的集合

集合本身是可以改的,所以集合不能放进集合,也不能当字典的键。要这个能力,就用 frozenset——冻结版集合,建好之后一个都改不了。

Python
fs = frozenset([1, 2, 3])
print(fs)
print(len(fs), 2 in fs)
print(sorted(fs))

输出:

Python
frozenset({1, 2, 3})
3 True
[1, 2, 3]

想改它?方法和列表一样,直接没有:

Python
fs = frozenset([1, 2])
fs.add(3)

运行后会报错(逐字照抄解释器):

报错
AttributeError: 'frozenset' object has no attribute 'add'

换来的好处是:它能当字典的键,也能被放进别的集合里。

Python
d = {frozenset([1, 2]): '一对'}
print(d[frozenset([1, 2])])
s = {frozenset([1]), frozenset([2])}
print(len(s))

输出:

输出
一对
2

四个运算它全都能用(因为不需要改动自己):

Python
print(sorted(frozenset([1, 2, 3]) & {2, 3, 4}))

输出:

输出
[2, 3]

课程思政|工匠精神与严谨求实 · 该冻结的,就别让它变

普通集合自己能被改,所以放不进别的集合,也当不了字典的键;frozenset 是冻结版,建好之后一个元素都改不动,换来的是它能安全地当键、能被塞进别的集合。这也是一种做事方式:有些数据一旦定下来,就该锁死不让它变。成绩册、合同里的金额、统计口径,都该留一份「冻住」的,之后谁动了它,一查账就知道。

十、类型转换:四种容器怎么互转

到这儿,四种组合数据类型——列表、元组、字典、集合——就都学完了。实际写代码时经常要在它们之间来回转,靠的就是几个同名的转换函数。

函数把一个东西变成例子
list(x)列表list('abc') → ['a', 'b', 'c']
tuple(x)元组tuple([1, 2]) → (1, 2)
set(x)集合(顺手去重)set([1, 1, 2]) → {1, 2}
dict(x)字典(元素要是键值对)dict([('a', 1)]) → {'a': 1}
str(x)字符串str(123) → '123'

列表 / 元组 / 集合:三者随便转

Python
lst = [3, 1, 2, 1]
print(set(lst))        # 去重
print(tuple(lst))
print(list(set(lst)))  # 去过重的列表

输出:

输出
{1, 2, 3}
(3, 1, 2, 1)
[1, 2, 3]

注意 list(set(...)) 出来后的顺序不保证——集合本身是无序的。要固定顺序,先 sorted() 一下:

Python
lst = [3, 1, 2, 1]
print(sorted(set(lst)))

输出:

输出
[1, 2, 3]

字典转成别的:直接转只会给「键」

Python
d = {'a': 1, 'b': 2}
print(list(d))           # 键
print(list(d.keys()))    # 还是键
print(list(d.values()))  # 值
print(list(d.items()))   # (键, 值) 对

输出:

输出
['a', 'b']
['a', 'b']
[1, 2]
[('a', 1), ('b', 2)]

转回字典:每个元素必须是「键值对」

Python
pairs = [('a', 1), ('b', 2)]
print(dict(pairs))
print(dict([['x', 9], ['y', 8]]))   # 用列表写也行

输出:

输出
{'a': 1, 'b': 2}
{'x': 9, 'y': 8}

如果元素不是「长度 2 的一对」,就会报错:

Python
print(dict([1, 2, 3]))

运行后会报错(逐字照抄解释器):

报错
TypeError: cannot convert dictionary update sequence element #0 to a sequence

字符串 ↔ 列表

Python
print(list('abc'))
print(''.join(['a', 'b', 'c']))
print('1,2,3'.split(','))

输出:

输出
['a', 'b', 'c']
abc
['1', '2', '3']

list(字符串) 会把它拆成一个个字符;反过来 ''.join(列表) 能把一堆字符串再拼回去(join 要求里面的元素都是字符串)。

我想……怎么写
列表去重list(set(lst))
把元组变成能改的列表list(t)
把列表锁成元组tuple(lst)
取字典所有的键list(d) 或 list(d.keys())
取字典的键值对list(d.items())
把键值对列表变回字典dict(pairs)
把字符串拆成列表list(s) 或 s.split(分隔符)
把列表拼成字符串''.join(lst)
转换都是新建一个对象,原来的变量不受影响。另外记住最容易记混的一条:list(字典) 得到的是键,不是值、也不是键值对。

十一、十个基础案例

1. 一份点单记录去重

Python
nums = [8, 3, 8, 5, 3, 5]
print(sorted(set(nums)))

输出:

输出
[3, 5, 8]

2. 去重,但保留第一次出现的顺序

Python
orders = ['奶茶', '炸鸡', '奶茶', '可乐', '炸鸡']
print(list(dict.fromkeys(orders)))

输出:

输出
['奶茶', '炸鸡', '可乐']

3. 一句备注里出现了哪些不重复的字

Python
text = '半糖去冰半'
print(sorted(set(text)))

输出:

输出
['冰', '半', '去', '糖']

4. 数一数有几个不同的字

Python
text = '半糖去冰'
print(len(set(text)))

输出:

输出
4

5. 判断两份歌单有没有重合

Python
a = ['晴天', '稻香']
b = ['起风了', '告白气球']
print(set(a).isdisjoint(b))
print(bool(set(a) & set(b)))

输出:

输出
True
False

6. 两份歌单都有的歌

Python
a = ['晴天', '稻香', '起风了', '稻香']
b = ['起风了', '稻香', '七里香']
print(sorted(set(a) & set(b)))

输出:

输出
['稻香', '起风了']

7. 只在其中一份里出现的歌

Python
a = ['晴天', '稻香', '起风了']
b = ['起风了', '稻香', '七里香']
print(sorted(set(a) ^ set(b)))

输出:

输出
['七里香', '晴天']

8. 检查甜度是不是合法选项

Python
options = {'无糖', '三分糖', '七分糖'}
choice = '三分糖'
if choice in options:
    print('你点了', choice)
else:
    print('没有这个选项')

输出:

输出
你点了 三分糖

9. 一单里有几种不同的口味

Python
orders = ['奶茶', '咖啡', '奶茶', '可乐', '咖啡']
print('总杯数:', len(orders))
print('不同口味:', len(set(orders)))

输出:

输出
总杯数: 5
不同口味: 3

10. 把盲盒编号排好序再输出

Python
s = {5, 3, 9, 1}
print(sorted(s))
print(sorted(s, reverse=True))

输出:

输出
[1, 3, 5, 9]
[9, 5, 3, 1]

十二、常见坑

坑 1:空集合写成 {}

这是集合的头号大坑。{} 是空字典,一调用集合方法就报 AttributeError。

Python
s = set()      # 正确:空集合
print(type(s))

输出:

输出
<class 'set'>

坑 2:想用下标取元素

Python
s = {1, 2, 3}
print(s[0])

运行后会报错(逐字照抄解释器):

报错
TypeError: 'set' object is not subscriptable

集合无序,没有「第 0 个」。要按位置取,先转到列表:list(s)[0]——但那个「第 0 个」是谁并不确定,通常说明你该用列表。

坑 3:把列表塞进集合

Python
s = {1, 2}
s.add([3, 4])

运行后会报错(逐字照抄解释器):

报错
TypeError: unhashable type: 'list'

元素必须不可变。想放一组数,就用元组:s.add((3, 4))。

坑 4:以为集合会记住顺序

print(s) 出来的顺序不保证和你写进去的一致,同一个程序不同次运行也可能不一样。要固定顺序,一律先 sorted()。

Python
s = {3, 1, 2}
print(sorted(s))       # 每次都一样

输出:

输出
[1, 2, 3]

坑 5:用 remove 删不存在的元素

Python
s = {1, 2, 3}
s.remove(99)

运行后会报错(逐字照抄解释器):

报错
KeyError: 99

不确定在不在,改用 s.discard(99),它会安静地什么都不做。

坑 6:把 <= 当成「小于等于」

Python
print({1, 2} <= {1, 2})     # True:是子集(等于也算)
print({1, 2} < {1, 2})      # False:不是真子集

输出:

输出
True
False

集合之间的 <= / < / >= / > 全部是「子集 / 真子集 / 超集 / 真超集」,和数字比大小完全无关。

AI 助手小贴士|集合的价值在去重和比对,用应用题练。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:出 3 道集合应用题:统计一篇文章里不重复的字数、找出两份名单都出现的人、检查学号有没有重复。等我写完点评

十三、报错手册

下面这些报错都是真实运行出来的,照抄本机解释器的原文。看到眼熟的,直接对照处理。

用下标取集合的元素

Python
s = {1, 2, 3}
print(s[0])

运行后会报错(逐字照抄解释器):

报错
TypeError: 'set' object is not subscriptable

原因:集合无序,没有「第几个」。要按下标取,请改用列表。

删一个不存在的元素

Python
s = {1, 2, 3}
s.remove(99)

运行后会报错(逐字照抄解释器):

报错
KeyError: 99

原因:remove 要求元素必须在。不确定就用 discard。

把列表放进集合

Python
s = {[1, 2], 3}

运行后会报错(逐字照抄解释器):

报错
TypeError: unhashable type: 'list'

原因:列表会变,不能算「固定位置」(不可哈希)。改用元组 (1, 2)。

空集合写成 {},再调用 add

Python
s = {}
s.add(1)

运行后会报错(逐字照抄解释器):

报错
AttributeError: 'dict' object has no attribute 'add'

原因:{} 建出来的是空字典,字典没有 add。空集合要写 set()。

用符号做运算,但另一边是列表

Python
print({1, 2, 3} & [2, 3])

运行后会报错(逐字照抄解释器):

报错
TypeError: unsupported operand type(s) for &: 'set' and 'list'

原因:& 只认集合。要么把列表转成集合(set([2, 3])),要么改用方法 {1, 2, 3}.intersection([2, 3])。

两个集合相加

Python
print({1} + {2})

运行后会报错(逐字照抄解释器):

报错
TypeError: unsupported operand type(s) for +: 'set' and 'set'

原因:集合不支持 +。「合起来」要用并集 | 或 union()。

想给 frozenset 加元素

Python
fs = frozenset([1, 2])
fs.add(3)

运行后会报错(逐字照抄解释器):

报错
AttributeError: 'frozenset' object has no attribute 'add'

原因:frozenset 是冻结的,一个都改不了。它就是靠「不能改」才能当字典的键。

想给集合排序

Python
s = {3, 1, 2}
s.sort()

运行后会报错(逐字照抄解释器):

报错
AttributeError: 'set' object has no attribute 'sort'

原因:集合没有 sort(它本来就无序)。用内置函数 sorted(s) 得到一个新列表。

对空集合 pop

Python
s = set()
s.pop()

运行后会报错(逐字照抄解释器):

报错
KeyError: 'pop from an empty set'

原因:里面一个元素都没有,没得删。删之前先判空:if s:。

AI 助手小贴士|交、并、差这些概念用生活场景(名单比对)让 AI 直接写给你看,比文字定义直观。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:两个班的学生名单分别存在两个列表里,怎么用集合找出:两个班都有的人、只在 1 班的人、合在一起去重后的名单?写出代码并加中文注释

十四、随堂自测(12 题)

点击选项即可判分,选错的题会立刻展开解析。做完可以看到正确率和错题清单,也可以重新答题。

已答 0 / 12 · 正确 0 —

1想把一个列表里重复的元素去掉,最省事的一行是?

  • A. nums = list(set(nums))
  • B. nums = set(nums) + []
  • C. nums.remove(nums)
  • D. nums = sorted(nums)
答案:A。先用 set() 把重复的吃掉,再用 list() 转回列表。B 那行会报错(集合不能加列表),D 只是排序,重复的还在。

2下面哪一行创建的是一个空集合?

  • A. s = {}
  • B. s = []
  • C. s = set()
  • D. s = ()
答案:C。空集合只能用 set()。{} 是空字典(最容易踩的坑),[] 是空列表,() 是空元组。

3s = {1, 2, 3},执行 print(s[0]) 会发生什么?

  • A. 输出 1
  • B. 报 TypeError: 'set' object is not subscriptable
  • C. 输出 {1}
  • D. 输出 None
答案:B。集合无序,没有「第 0 个」,所以不能用下标。要按下标取,先转成列表 list(s)。

4下面哪个不能放进集合?

  • A. 数字 10
  • B. 字符串 'abc'
  • C. 元组 (1, 2)
  • D. 列表 [1, 2]
答案:D。集合的元素必须不可变(可哈希)。列表会变,塞进去会报 TypeError: unhashable type: 'list';想放一组数就用元组。

5s = {1, 2, 3},想删掉 4、而且「没有这个元素时也不报错」,该用哪个?

  • A. s.remove(4)
  • B. s.discard(4)
  • C. s.pop(4)
  • D. s.delete(4)
答案:B。discard() 删不存在的元素时安静地什么都不做;remove() 会报 KeyError: 4。集合里也没有 delete 这个方法。

6{1, 2, 3} & {2, 3, 4} 的结果是?

  • A. {1, 2, 3, 4}
  • B. {1, 4}
  • C. {2, 3}
  • D. {1, 3}
答案:C。& 是交集,取两边都有的元素,所以是 {2, 3}。取全部用并集 |。

7{1, 2, 3} ^ {2, 3, 4} 的结果是?

  • A. {2, 3}
  • B. {1}
  • C. {1, 2, 3, 4}
  • D. {1, 4}
答案:D。^ 是对称差,取「只出现在一边」的元素:1 只在左边、4 只在右边,共同的 2、3 被去掉。

8集合里 x in s 判断的是?

  • A. 元素 x 在不在集合 s 里
  • B. 下标 x 有没有越界
  • C. 集合里有没有以 x 命名的键
  • D. 集合是不是空的
答案:A。集合上的 in 就是问「这个元素在不在里面」。注意和字典不同——字典的 in 查的是键,集合查的就是元素本身。

9{1, 2} <= {1, 2, 3} 的结果是?

  • A. 报错,集合不能比较
  • B. True,<= 在这里表示「是子集」
  • C. False,因为 1 和 3 不相等
  • D. 返回 {1, 2}
答案:B。集合之间的 <= 是「子集」,< 是「真子集」。{1, 2} 的元素全在 {1, 2, 3} 里,所以是 True。

10关于 frozenset,下面说法正确的是?

  • A. 它和 set 完全一样,只是名字长一点
  • B. 它可以 add 但不能 remove
  • C. 它不可变,所以能当字典的键、也能放进别的集合
  • D. 它只能装数字
答案:C。frozenset 是「冻结的集合」,建好就一个都改不了(调用 add 会报 AttributeError)。正因为不可变,它能当字典的键。

11要把列表 [1, 1, 2, 3] 去重后变回列表,下面哪一句对?

  • A. list(set([1, 1, 2, 3]))
  • B. set(list([1, 1, 2, 3]))
  • C. list(tuple([1, 1, 2, 3]))
  • D. set([1, 1, 2, 3]).list()
答案:A。先用 set() 去重,外面再套 list() 转回列表。注意转回来后的顺序不保证(集合本身无序);set 也没有 .list() 这种方法。

12把字典 d 转成列表时,list(d) 得到的是?

  • A. 所有的值
  • B. 所有 (键, 值) 对
  • C. 报错,字典不能转列表
  • D. 所有的键
答案:D。直接 list(d) 得到的是键的列表。要键值对用 list(d.items()),要值用 list(d.values())。这是最容易记混的一处。