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

一、数据类型是什么

写程序的时候,我们往变量里放的东西五花八门:有的是数字(18),有的是文字("小满"),有的是一串东西(["奶茶", "薯条"])。

Python 会给每一样东西都贴上一个类型标签,告诉你“这是哪一类东西”。这个标签就是数据类型。

打个比方:厨房里有杯子、有桶、有保鲜盒。杯子装水,桶装米,保鲜盒装剩菜。不同的东西要放进不同的容器,数据类型就是这个“容器”。

1.1 为什么一定要区分类型

因为类型决定了这个东西能怎么用。同样是加号:

Python
print(5 + 3)        # 8      数字 + 数字 = 加法
print("5" + "3")    # 53     文字 + 文字 = 首尾拼起来

一个是数学加法,一个是文字拼接,结果完全不一样。如果搞混了,程序就直接报错:

Python
print("5" + 3)
# 报错:TypeError: can only concatenate str (not "int") to str

报错里出现 TypeError,意思就是“类型不对”。新手看到这个错,第一反应就该是:这两个东西的类型是不是不一样?

1.2 用 type() 看一眼类型

不确定一个值是什么类型,用 type() 套一下,它会直接告诉你答案:

Python
print(type(10))         # <class 'int'>
print(type(3.14))       # <class 'float'>
print(type("小满"))     # <class 'str'>
print(type([1, 2]))     # <class 'list'>
print(type((1, 2)))     # <class 'tuple'>
print(type({1, 2}))     # <class 'set'>
print(type({"a": 1}))   # <class 'dict'>
print(type(True))       # <class 'bool'>

下面这张表把八种类型对上号。这一整份教程,就是把这八行一行一行讲清楚。

值长什么样类型名中文名一句话说明
10 / 3.14int / float整数 / 浮点数数字,可做加减乘除
"小满"str字符串文字,用引号包起来
[1, 2, 3]list列表一串东西,能增能删
(1, 2, 3)tuple元组一串东西,定了就不能改
{"a": 1}dict字典成对的“名字→内容”
{1, 2, 3}set集合不重复的一堆东西
True / Falsebool布尔只有“真”和“假”
2 + 3jcomplex复数带虚部,初学了解即可
遇到类型问题,先问 type()。把 type(你的变量) 打印出来看一眼,十次有八次问题当场就明白了。
本篇是「点名册」,只求混个脸熟。八种类型各点一次名就行,不必背、更不必全懂——字符串第 10 篇讲、列表第 16 篇讲、元组第 17 篇讲、字典第 20 篇讲、集合第 21 篇讲,到时候每样都有一整篇细细掰开。

课程思政|数据安全与法治素养 · 给每类数据贴对标签

Python 会给每样东西贴一个类型标签,类型不同,能做的事就不同。数据工作里也是这样:一份表格里哪些是姓名、哪些是成绩、哪些是联系方式,先分清楚才好处理。能拿到不等于可以随手放,给数据贴对标签、把敏感字段单独标出来,是每个数据人最基本的规矩。

二、数字(int / float / complex)

数字是用来算数的,日常用到的其实只有两种:没小数点的叫整数(int),有小数点的叫浮点数(float)。

Python
age = 18            # 整数 int
price = 9.9         # 浮点数 float
score = -15         # 负数也是整数
big = 2 ** 100      # Python 的整数可以非常大,不会溢出

print(type(age))    # <class 'int'>
print(type(price))  # <class 'float'>

2.1 能做的运算

加减乘除和数学里一样。有四个地方和数学课本不太一样,记住就行:

运算符名字例子结果要注意
/除法7 / 23.5结果一定是小数,哪怕整除了也是 2.0
//整除7 // 23只留整数部分,把小数点后面砍掉
%取余7 % 21算“剩下多少”,最常用来判断奇偶
**幂2 ** 101024就是 2 的 10 次方
Python
print(7 / 2)      # 3.5    真除法
print(4 / 2)      # 2.0   ← 注意:是 2.0 不是 2
print(7 // 2)     # 3      整除
print(7 % 2)      # 1      取余,结果是 1 说明 7 是奇数
print(2 ** 10)    # 1024   2 的 10 次方
判断一个数是奇数还是偶数,标准写法是看余数:n % 2 == 0 就是偶数,n % 2 == 1 就是奇数。

2.2 复数和下划线(了解即可)

Python 还有一种复数,虚部后面带个 j。初学者基本用不上,知道有这么个东西就行:

Python
z = 2 + 3j
print(z)         # (2+3j)
print(type(z))   # <class 'complex'>

另外,数字很大时可以用下划线分开,纯粹为了方便眼睛看,程序里完全一样:

Python
print(1_000_000)        # 1000000
print(1_000_000 == 1000000)   # True
一个新手必踩的坑:小数算不准。计算机用二进制存小数,有些十进制小数存不精确:
Python
print(0.1 + 0.2)              # 0.30000000000000004
print(0.1 + 0.2 == 0.3)       # False  ← 别用 == 直接比小数!
这不是 Python 的毛病,所有编程语言都这样。要比较小数,写成 abs(a - b) < 0.000001;要保留两位小数,用 round(0.1 + 0.2, 2) 得到 0.3。

三、字符串(str)

字符串就是一段文字。只要用引号包起来,不管是中文、英文、还是数字,都算字符串。

Python
name = "小满"              # 双引号
city = '广州'              # 单引号,效果一样
message = "今年18岁"       # 数字在引号里也算文字
long_text = """第一行
第二行"""                  # 三引号可以跨行
单引号和双引号没有区别,挑一个用着顺手的一直用就行。三引号专门用来写多行文字。

3.1 拼接和重复

Python
print("Python" + "编程")    # Python编程    加号=首尾接起来
print("哈哈" * 3)           # 哈哈哈哈哈哈   乘号=重复几遍
print("-" * 20)             # --------------------  常用来画分隔线
想让数字和文字拼在一起,必须先把数字转成字符串,否则报错:
Python
print("年龄:" + 18)              # 报错 TypeError
print("年龄:" + str(18))         # 年龄:18   ✓
更省事的办法是用上一篇里的 f 字符串:f"年龄:{18}"。

3.2 索引和切片

字符串里的每个字符都有自己的位置编号,从 0 开始数:

Python
s = "Hello, World!"

print(s[0])      # H    第 0 个(也就是第一个)
print(s[-1])     # !    最后一个(负数从右边数)
print(s[0:5])    # Hello    从 0 取到 5(不含 5)
print(s[7:])     # World!   从 7 一直取到最后
print(len(s))    # 13   一共几个字符
写法含义结果
s[0]第 0 个字符(第一个)H
s[-1]最后 1 个字符!
s[0:5]第 0 到第 4 个(不含第 5 个)Hello
s[7:]第 7 个到最后World!
s[:5]开头到第 4 个Hello
s[0:5] 取到的是 5 个字符,不是 6 个——“含头不含尾”,写 0 到 5 就取 0、1、2、3、4。这是新手错得最多的一条。

3.3 字符串不能改(很重要)

字符串属于不可变类型:一旦写好,里面任何一个字符都不能单独修改。

Python
s = "hello"
s[0] = "H"
# 报错:TypeError: 'str' object does not support item assignment

想改只能重新拼一个新字符串:

Python
s = "hello"
s = "H" + s[1:]      # 取第 1 个到最后,前面接个 H
print(s)             # Hello
注意区分这两件事:不能改里面的字符,但可以让变量指向一个新字符串。前者不允许,后者随便用。

3.4 常用的几个操作

Python
s = "Hello, World!"

print(s.upper())                # HELLO, WORLD!   全变大写
print(s.lower())                # hello, world!   全变小写
print(s.replace("World", "Python"))   # Hello, Python!  替换文字
print("World" in s)             # True   有没有这个词
print(len(s))                   # 13     长度
s.upper() 这类方法不会改动原字符串,而是返回一个新的给你。写 s.upper() 之后 s 还是原来的样子,想用结果得接住:s2 = s.upper()。

四、列表(list)

列表是一串排好队的东西,用方括号 [] 包起来,中间用逗号隔开。

它有三个特点:有序(每个元素有固定位置)、可变(能加能删能改)、可重复(同一个值可以出现多次)。

Python
toppings = ["珍珠", "椰果", "布丁"]
scores = [85, 92, 78]
mixed = [1, "珍珠", 3.14, True]     # 一个列表里可以放不同类型
empty = []                          # 空列表
列表最大的优点就是能装不同类型的东西,这一点是很多语言做不到的。

4.1 取出元素

和字符串一样,用方括号加位置编号(索引),从 0 开始数:

Python
toppings = ["珍珠", "椰果", "布丁"]

print(toppings[0])    # 珍珠   第 0 个
print(toppings[1])    # 椰果
print(toppings[-1])   # 布丁   最后一个
print(len(toppings))  # 3      一共几个
记不住从 0 开始?就想成“第一个的编号是 0”,后面的顺次加一。-1 永远指最后一个,取最后一个元素用它最保险。

4.2 增、删、改

这是列表最常用的三个动作,对照着记:

想干什么怎么写说明
在末尾加一个toppings.append("西米")最常用,永远加到最后
在指定位置插入toppings.insert(1, "仙草")插到第 1 个位置,原来后面的都往后挪
修改某个元素toppings[0] = "寒天"把第 0 个换掉
删除指定的值toppings.remove("布丁")按内容删,找不到会报错
删除指定位置toppings.pop()不写参数删最后一个,也可以写 pop(0)
看有几个元素len(toppings)长度
Python
order = ["珍珠", "椰果", "牛奶"]

order.append("布丁")             # 末尾加
print(order)   # ['珍珠', '椰果', '牛奶', '布丁']

order[1] = "仙草"                # 改第 1 个
print(order)   # ['珍珠', '仙草', '牛奶', '布丁']

order.remove("牛奶")             # 按值删
print(order)   # ['珍珠', '仙草', '布丁']

last = order.pop()               # 弹出最后一个
print(last)                      # 布丁
print(order)   # ['珍珠', '仙草']

4.3 切片:一次取一串

Python
snacks = ["薯条", "鸡翅", "爆米花", "汉堡", "可乐"]

print(snacks[0:3])    # ['薯条', '鸡翅', '爆米花']   取前三个(不含第 3 个)
print(snacks[:2])     # ['薯条', '鸡翅']             从头取两个
print(snacks[2:])     # ['爆米花', '汉堡', '可乐']   从第 2 个取到最后
print(snacks[-2:])    # ['汉堡', '可乐']             最后两个
切片的规则和字符串完全一样(含头不含尾),学会一个两个都会。切片取出来的是新列表,改它不会影响原来的。

五、元组(tuple)

元组长得和列表很像,区别是把方括号换成圆括号 (),但有个关键不同:元组一旦创建就不能修改。

列表 list元组 tuple
符号[]()
能不能改能增能删能改定了就改不了
取值方式索引、切片索引、切片(一样)
适合放什么会变的数据固定不变的数据
生活中的样子购物车(随时加东西)身份证号、坐标(不能变)
Python
point = (10, 20)             # 一个坐标
rgb = (255, 128, 0)          # 一个颜色
weekdays = ("周一", "周二", "周三")

print(point[0])     # 10   取值和列表一样
print(point[-1])    # 20
print(len(rgb))     # 3
print(rgb[0:2])     # (255, 128)   也能切片

5.1 不能改,硬改就报错

Python
point = (10, 20)
point[0] = 5
# 报错:TypeError: 'tuple' object does not support item assignment
报错信息里的关键词是 does not support item assignment,意思是“不支持给元素赋值”。看到它,就知道你在改一个不允许改的东西(元组或字符串)。

5.2 只有一个元素时,必须加逗号

这是元组最容易踩的坑。想表示“只有一个元素的元组”,必须在元素后面加个逗号:

Python
a = (5)      # 这不是元组!括号只是普通括号,a 是整数
b = (5,)     # 这才是元组,注意那个逗号

print(type(a))   # <class 'int'>
print(type(b))   # <class 'tuple'>
空元组写 () 就可以。单个元素的元组一定要带逗号——这个逗号不是排版习惯,是语法要求。

5.3 一个好用的特性:解包

元组可以一次性把里面的值分给几个变量,这在处理坐标、成对数据时特别方便:

Python
point = (10, 20)
x, y = point            # 一次分开
print(x)    # 10
print(y)    # 20

# 交换两个变量的值,Python 里一行就够
a, b = 1, 2
a, b = b, a
print(a, b)   # 2 1
这里的 a, b = 1, 2 其实右边就是一个元组 (1, 2),只是括号可以省略。

课程思政|诚信与职业操守 · 定了的事,就别改

元组一旦创建就不能改,身份证号、坐标这类东西正该如此,硬改只会得到一个报错。做人做事也是这个道理:答应下来的事、公示出去的数据,不能今天一个样、明天一个样。写好的承诺和核对无误的数据,就该像元组一样稳,改不动,才让人放心。

六、字典(dict)

字典存的是成对的数据:一个“名字”,对应一个“内容”。用花括号 {} 包起来,写成 {键: 值}。

前面的名字叫键(key),后面的内容叫值(value)。就像查字典:给一个词(键),查它的解释(值)。

Python
user = {
    "name": "小满",
    "age": 18,
    "gender": "男",
}
print(user)              # {'name': '小满', 'age': 18, 'gender': '男'}
键和值之间是冒号,每对之间用逗号。这两处最容易写错,写错就报语法错误。

6.1 取值、改值、加新值

Python
user = {"name": "小满", "age": 18}

print(user["name"])     # 小满     用键取值,不是用位置编号
user["age"] = 19        # 改:键已存在就是修改
print(user["age"])      # 19
user["height"] = 175    # 加:键不存在就是新增
print(user)
# {'name': '小满', 'age': 19, 'height': 175}
字典用键取值,不用编号。user[0] 是错的(除非你正好有个键叫 0)。这是从列表转过来最容易搞混的地方。

6.2 取不到键怎么办:用 get()

直接写 user["score"],如果字典里没有这个键,程序会直接报错中断:

Python
user = {"name": "小满"}
print(user["score"])
# 报错:KeyError: 'score'

KeyError 是新手最常见的报错之一。稳妥的写法是用 get(),取不到不会崩,只会给你一个 None:

写法键存在键不存在
user["score"]返回值报 KeyError,程序中断
user.get("score")返回值返回 None,程序继续跑
user.get("score", 0)返回值返回你指定的默认值 0
不确定键一定存在,就用 get()。尤其是键来自用户输入或者其他程序的时候,用 get() 能少写很多防错代码。

6.3 两条规则

  1. 键必须唯一。后面写的同名键会覆盖前面的值。
  2. 键必须是不可变的类型,通常是字符串或数字。列表不能做键(会报 TypeError: unhashable type: 'list'),因为列表能改。
Python
d = {"a": 1, "a": 2}
print(d)        # {'a': 2}   同名键,后面的覆盖前面

good = {"name": "小满"}       # 字符串做键 ✓
ok = {100: "满分"}            # 数字做键 ✓
# bad = {[1, 2]: "x"}         # 列表做键 ✗ 报错

6.4 把字典里的内容一个个拿出来

Python
user = {"name": "小满", "age": 18}

print(list(user.keys()))      # ['name', 'age']        所有键
print(list(user.values()))    # ['小满', 18]           所有值

for k, v in user.items():     # 一次拿到键和值
    print(k, "=", v)
# name = 小满
# age = 18
较新的 Python 3 版本里,字典会记住你放进去的顺序,打印出来和写的顺序一致。但记住一点:取值永远靠键,不靠顺序——别写“第 0 个键”这种代码。

七、集合(set)

集合也是用花括号 {},但它只存“不一样的东西”:重复的自动去掉,而且没有顺序。

Python
nums = {1, 2, 3, 3, 4}
print(nums)          # {1, 2, 3, 4}   重复的 3 只剩一个

orders = ["珍珠", "椰果", "珍珠"]        # 两份珍珠,重复了
print(sorted(set(orders)))   # ['椰果', '珍珠']   套 set() 去重,重复的只剩一份
集合最拿手的活就是去重。一批名单里有重复的,套一层 set() 就干净了:
Python
names = ["小满", "阿宝", "小满", "小可"]
print(sorted(set(names)))    # ['小可', '小满', '阿宝']
反过来想“有几种不同的东西”,也用它:len(set(names)) 就是种类数。

7.1 不能按位置取,只能问“在不在”

集合没有顺序,所以不能用 nums[0] 这种写法:

Python
nums = {1, 2, 3}
print(nums[0])
# 报错:TypeError: 'set' object is not subscriptable

想知道某个东西在不在,用 in:

Python
nums = {1, 2, 3}
print(3 in nums)      # True
print(9 in nums)      # False
报错里的 not subscriptable 意思是“不能用方括号下标取”。看到它就检查:是不是对集合用了 [0]?

7.2 添加和删除

Python
nums = {1, 2, 3}
nums.add(4)          # 加一个
print(nums)          # {1, 2, 3, 4}

nums.discard(1)      # 删一个(不存在也不报错)
print(nums)          # {2, 3, 4}
注意名字不一样:集合用 add(),列表用 append()。写混了会提示“没有这个属性”。

7.3 集合运算(它的另一个强项)

数学里的交、并、差,集合直接支持,写起来非常短:

运算符号例子结果含义
并集|{1,2,3} | {3,4,5}{1, 2, 3, 4, 5}两边合起来,重复的只算一个
交集&{1,2,3} & {3,4,5}{3}两边都有的
差集-{1,2,3} - {3,4,5}{1, 2}左边有、右边没有的
对称差^{1,2,3} ^ {3,4,5}{1, 2, 4, 5}只在一方出现过的
别把 & 和 and 搞混:这里 & 是集合求交集,and 是逻辑判断;就像 | 是求并集,or 是逻辑判断,它们作用在完全不同的东西上。

7.4 空集合的写法是个例外

Python
a = {}          # 这是空字典,不是空集合!
b = set()       # 这才是空集合

print(type(a))  # <class 'dict'>
print(type(b))  # <class 'set'>
空集合只能用 set()。因为 {} 被字典先占用了。非空的集合可以写 {1, 2, 3},这没有问题。

八、布尔(bool)

布尔是最简单也最重要的类型,它只有两个值:True(真)和 False(假)。

写的时候首字母必须大写,true 和 false 都是错的。它主要用在判断上:程序要不要走这一步,就看这个值是真是假。

Python
is_student = True
is_empty = False

print(5 > 3)      # True     比较的结果就是布尔值
print(5 == 5)     # True
print(5 < 3)      # False
print(type(True)) # <class 'bool'>

8.1 哪些东西算“假”

这一点掌握了能省很多事。Python 里下面这些值,在判断时都当假处理:

类型假值长什么样说明
数字0、0.0零就是假
字符串""空字符串是假
列表[]空列表是假
元组()空元组是假
字典 / 集合{}、set()空的都是假
特殊值None表示“什么都没有”
布尔False本身就是假

除了上面这些,其他都是真。有两处新手最容易看错,专门点一下:

Python
print(bool("0"))     # True   ← 有内容的字符串!"0" 不是零
print(bool(" "))     # True   ← 一个空格也算有内容
print(bool(0))       # False  ← 这个才是假
print(bool([0]))     # True   ← 列表里有一个元素 0,不是空列表
print(bool([]))      # False  ← 空列表才是假
判断一个列表是不是空的,不用写 len(lst) == 0,直接 if lst: 就行——空列表自动当假。这是 Python 的地道写法。

8.2 bool 其实也是数字

有个冷知识:True 当作数字时等于 1,False 等于 0。所以它们能直接参与计算。

Python
print(True + 1)        # 2
print(True == 1)       # True
print(False == 0)      # True
print(True * 100)      # 100
知道这个只是为了看得懂别人的代码,自己写的时候别故意拿 True 去算数——那样写出来别人读不懂。

8.3 实际用在哪

Python
age = 18
if age >= 18:
    print("成年了")

names = []
if not names:                 # 空列表当假,not 一下就变真
    print("名单是空的")

这些判断的写法在后面的控制结构章节里会详细讲,这里只要记住:布尔值就是程序的“岔路口指示牌”。

AI 助手小贴士|八种类型的信息量不小,让 AI 收拢成一张对比表,一眼看全局。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:把 Python 的 int、float、str、list、tuple、dict、set、bool 整理成一张对比表:是否有序、可不可变、典型用途、一个字面量例子

九、七种类型总览与选择建议

把前面讲的七种常用类型放在一张表里对照(第 8 种 complex 复数只在 2.2 节提过一次、日常几乎用不到,就不占一行了),先看符号、再看能不能改,最后看有没有重复:

类型定义符号有序吗能改吗能重复吗生活中的例子
int / float没有专属符号—不能—年龄、价格
str'' "" """有序不能可以"广州市天河区"
list[]有序能可以购物车 ['奶茶','薯条']
tuple()有序不能可以坐标 (10, 20)
dict{键: 值}有序(较新版本)能键不能,值可以通讯录 {'小满': 138}
set{} / set()无序能不能去重后的名单
bool没有专属符号—不能—True / False
“有序”的意思是每个元素有固定位置,能用 [0] 这种编号取出来。集合无序,所以只能问“在不在”,不能问“第几个”。

9.1 看到需求怎么选

你的需求选它原因
要频繁增加、删除、修改列表 list它就是为“会变”设计的
数据固定不变,不希望被改元组 tuple防止误改,更安全
要按名字快速找内容字典 dict给个键就能拿到值
要去重,或者做交并差集合 set自动去重 + 支持集合运算
就是一段文字字符串 str文字都用它
只要一个是 / 否的答案布尔 bool只有两个值
拿不定主意时问自己两句话:① 这个东西以后要改吗?要改就往 list / dict 想。② 我要按什么找它?按位置找用 list,按名字找用 dict。

9.2 怎么知道自己拿到的是什么类型

Python
data = [1, 2, 3]

print(type(data))                  # <class 'list'>
print(isinstance(data, list))      # True   是不是列表
print(isinstance(data, (list, tuple)))   # True   是列表或元组之一就行
type() 用来“看”,isinstance() 用来“判断”。写判断逻辑时用 isinstance(),它更稳。

十、可变与不可变(最容易栽的地方)

前面反复出现“可变 / 不可变”,这是数据类型里最需要真正理解的一点。先记住分组:

有哪些特点
可变(能改)list、dict、set原地就能改,改完还是同一个东西
不可变(改不了)int、float、str、tuple、bool想“改”只能造一个新的

10.1 一个必须知道的陷阱

看下面这段代码,先猜猜 a 最后是什么:

Python
a = [1, 2]
b = a          # 注意这一行
b.append(3)

print(a)       # [1, 2, 3]   ← a 也变了!
print(b)       # [1, 2, 3]

很多人以为 b = a 是“把 a 复制一份给 b”,不是的。它的意思是“让 b 也指向同一个列表”,就像给同一个盒子又贴了一张标签。改盒子里的东西,两张标签看到的都一样。

想让两个互不影响,得真的复制一份:

Python
a = [1, 2]
b = a.copy()       # 复制一份,互相独立
b.append(3)

print(a)           # [1, 2]      没受影响
print(b)           # [1, 2, 3]
字符串不会遇到这个问题(因为它不可变)。列表、字典、集合赋值给别人之前,先想一下:我是想共用,还是想各留一份?想各留一份就写 .copy()。

10.2 不可变的东西“改”的时候发生了什么

Python
s = "ab"
s = s + "c"        # 这一步不是原地改,而是造了个新字符串 "abc" 再让 s 指向它

t = (1, 2)
# t[0] = 9         # 元组连这个都做不到,直接报错

所以“不可变”不是“变量不能重新赋值”,而是“这个东西本身不能被改动”。变量随时可以指向别的东西。

10.3 一个例外:元组里放列表

元组保证的是它自己那一层不能改。如果里面装的是列表,那列表还是能改的:

Python
t = (1, [2, 3])
t[1].append(4)      # 改的是里面的列表,元组本身没动
print(t)            # (1, [2, 3, 4])
这个现象知道就好。做作业时别故意这么写——看起来是“不可变的元组”,实际里面还能变,容易把自己绕进去。

10.4 为什么要设计成不可变的

  1. 更安全。坐标、身份证号这类不该变的东西,用元组就不会被别的代码不小心改掉。
  2. 能当字典的键。只有不可变的东西才能做键,所以字符串和数字能当键,列表不行。
  3. 更快。Python 内部处理不可变对象效率更高(这个了解即可)。
一句话总结:要变用 list,不变用 tuple。名字、成绩这种会改的用列表;坐标、日期这种固定的用元组。

AI 助手小贴士|「可变与不可变」是本篇最深的坑,用判断题检验自己。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:出 3 道判断题:每题给一段对字符串、列表或元组操作的代码,让我判断会不会报错并说为什么

课程思政|工匠精神与严谨求实 · 以为复制了,其实没复制

很多人以为 b = a 是把列表复制一份,其实两张标签贴在同一个盒子上,改一处,两边一起变。现实里也常这样:同一份原始数据被多处引用,一处改动,别处跟着遭殃。动手之前先弄清是不是同一个对象,该真复制就真复制,别凭想当然下手。

十一、常见问题

下面这些报错,初学阶段几乎每个人都会遇到。看到眼熟的那条,照着“怎么办”改就行。

现象 / 报错原因怎么办
TypeError: can only concatenate str (not "int") to str字符串和数字直接用 + 拼先转成字符串 str(n),或用 f 字符串 f"年龄{age}"
TypeError: 'str' object does not support item assignment想改字符串里的某个字符字符串不可变。重新拼一个新串:s = "H" + s[1:]
TypeError: 'tuple' object does not support item assignment想改元组里的元素元组不可变。确实要改就改用列表 [] 存
(5) 被当成了整数单个元素的元组忘了加逗号写成 (5,),那个逗号不能少
KeyError: 'score'字典里没有这个键,却用了 d["score"]改用 d.get("score"),取不到返回 None 不会崩
TypeError: unhashable type: 'list'拿列表去当字典的键键换成字符串或数字。列表能改,所以不能做键
TypeError: 'set' object is not subscriptable对集合用了 s[0] 这种下标集合无序不能取第几个。改用 x in s 判断在不在
{} 建出来的不是空集合{} 被字典占用了空集合写 set()
int("3.5") 报 ValueErrorint() 只认整数字符串,不认小数点两步走:int(float("3.5")) 得到 3
0.1 + 0.2 不等于 0.3小数在计算机里存不精确(所有语言都这样)比较时用 abs(a-b) < 0.000001;要格式用 round(x, 2)
True 写成了 true布尔值必须首字母大写写 True / False
改了 b = a 之后 a 也跟着变了a、b 指向同一个列表,不是复制想各留一份写 b = a.copy()
遇到报错别慌,先做两件事:① 看最后一行,那里才是真正的原因,前面几行是它走过的路;② 看到 TypeError 就去查 type(),看到 KeyError 就去查键名拼写,看到 ValueError 就去查转换的内容合不合法。

AI 助手小贴士|本篇只求「脸熟」,每个类型后面都有一整篇细讲。AI 能帮你提前把「可变/不可变」这种大问题讲透——但它的解释要动手验证,以运行结果为准。

打开任意 AI 对话工具(网页版或 App 都可以),试试这样问:用「便利贴和刻字」这样的比喻解释 Python 可变类型和不可变类型的区别:为什么列表能改而元组不能?举两个会报错的例子

十二、随堂自测(10 题)

点击选项即可判分,答错的题会立刻显示解析。做完全部题目会给出正确率和错题清单。

已答 0 / 10 · 正确 0 —

1type(3.14) 打印出来是什么?

  • A. <class 'int'>
  • B. <class 'float'>
  • C. <class 'str'>
  • D. <class 'complex'>
答案:B。带小数点的数是浮点数 float。整数是 int(如 10),加了引号的数字是字符串 str(如 "3.14"),虚部带 j 的才是复数。

2执行 s = "hello" 之后再写 s[0] = "H",会发生什么?

  • A. s 变成 "Hello"
  • B. s 还是 "hello",但没有任何提示
  • C. 报 TypeError,字符串不能这样改
  • D. 报 KeyError
答案:C。字符串是不可变类型,不能单独改其中某个字符,会报 TypeError: 'str' object does not support item assignment。想改要重新拼一个:s = "H" + s[1:]。

3想表示“只有一个元素 5 的元组”,下面哪种写法是对的?

  • A. (5)
  • B. (5,)
  • C. [5]
  • D. {5}
答案:B。(5) 只是普通括号,类型还是整数;必须加逗号才被当成元组。[5] 是列表,{5} 是集合。

4从字典 user = {"name": "小满"} 里取 "age",但不确定这个键存不存在,怎么写最稳妥?

  • A. user["age"]
  • B. user.age
  • C. user("age")
  • D. user.get("age")
答案:D。user["age"] 键不存在会报 KeyError 让程序中断;get() 取不到时返回 None(也可以写 get("age", 0) 指定默认值),程序照常往下跑。

5想创建一个空集合,正确的写法是?

  • A. set()
  • B. {}
  • C. []
  • D. ()
答案:A。{} 创建出来的是空字典,不是空集合;空列表是 []、空元组是 ()。集合的空写法只有 set() 这一种。

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

  • A. {1, 2, 3, 4, 5}
  • B. {1, 2, 4, 5}
  • C. {3}
  • D. 报错,集合不能用 &
答案:C。& 是求交集,只保留两边都有的元素 → {3}。求并集用 | 得 {1, 2, 3, 4, 5},求差集用 - 得 {1, 2}。

7想把 "布丁" 追加到列表 order = ["珍珠", "椰果"] 的末尾,用哪个方法?

  • A. order.append("布丁")
  • B. order.add("布丁")
  • C. order.insert("布丁")
  • D. order.push("布丁")
答案:A。列表加到末尾用 append()。add() 是集合的方法,列表没有;insert() 需要两个参数 (位置, 元素),如 insert(1, "布丁");Python 列表里根本没有 push() 这个方法。

8下面哪个表达式的值是 False?

  • A. bool(1)
  • B. bool("0")
  • C. bool([0])
  • D. bool("")
答案:D。空字符串是假值。"0" 是有内容的字符串(假值只有空字符串),[0] 是含一个元素的列表也是真值,只有 0、""、[]、None 这些才是假。

9执行 a = [1, 2]、b = a、b.append(3) 之后,a 里面是什么?

  • A. [1, 2],不受影响
  • B. [1, 2, 3],跟着一起变了
  • C. [3]
  • D. 报错
答案:B。b = a 不是复制,而是让 a、b 指向同一个列表,改一个等于改这份数据。想让两者互不影响,要写 b = a.copy() 或 b = list(a)。

10有一批名单里有重复的名字,想去掉重复项,用哪种类型最方便?

  • A. 列表 list
  • B. 元组 tuple
  • C. 集合 set
  • D. 字符串 str
答案:C。集合的元素自动去重,set(["小满", "小满", "阿宝"]) 直接得到 {"小满", "阿宝"}。列表会原样保留重复项,元组不可改也不去重。