当前位置:首页>python>5 个 Python 数据类型陷阱,看完你会对 Python 有新认识

5 个 Python 数据类型陷阱,看完你会对 Python 有新认识

  • 2026-10-11 08:30:42
5 个 Python 数据类型陷阱,看完你会对 Python 有新认识

看起来是康庄大道,实则连环深坑

Python 的数据类型设计有不少反直觉的地方,bool 是 int 子类、浮点数精度、NaN 不等于自身……今天这 5 个坑,你可能不止踩过一个。


坑 1:字典键的哈希陷阱

这个坑我踩过,说出来你可能不信,当时 debug 了整整半天。

d = {True: 'yes', 1: 'one', 1.0: 'float_one'}
print(d)
print(len(d))

你觉得输出是什么?想好了吗?

实际是:{'True': 'float_one'} 1

因为 True == 1 == 1.0 且它们的哈希值相同,Python 认为它们是同一个键。后面的值会覆盖前面的。字典使用哈希值和 == 来判断键是否相同。

正确写法:


# 如果需要区分,用字符串作为键
d = {'True': 'yes', '1': 'one', '1.0': 'float_one'}
print(len(d))  # 3

踩坑现场:配置文件解析时,布尔值和数字混在一起做字典键,配置项莫名其妙地丢失了。


坑 2:空元组和逗号(猜猜输出)

这个问题我提 MR 的时候被 review 过,后来发现团队里有三个人都踩过。


a = (1)
b = (1,)
print(type(a))
print(type(b))

A. 都是 tupleB. <class 'int'><class 'tuple'>C. 报错

答案是 B。在 Python 中,创建元组的是逗号而不是括号。(1) 只是一个带括号的整数表达式,(1,) 才是一个只有一个元素的元组。空元组用 () 创建。这个语法设计经常让新手困惑,也是代码审查中常见的 bug 来源。


# 单元素元组必须加逗号
a = (1,)
print(type(a))  # <class 'tuple'>

踩坑现场:函数返回 return (result) 以为返回了元组,调用方解包直接报错。


坑 3:空元组和逗号(猜猜输出)

这是我见过的最隐蔽的 bug 之一,代码能跑,测试能过,但结果就是不对。


a = (1)
b = (1,)
print(type(a))
print(type(b))

A. 都是 tupleB. <class 'int'><class 'tuple'>C. 报错

答案是 B。在 Python 中,创建元组的是逗号而不是括号。(1) 只是一个带括号的整数表达式,(1,) 才是一个只有一个元素的元组。空元组用 () 创建。这个语法设计经常让新手困惑,也是代码审查中常见的 bug 来源。


# 单元素元组必须加逗号
a = (1,)
print(type(a))  # <class 'tuple'>

踩坑现场:函数返回 return (result) 以为返回了元组,调用方解包直接报错。


坑 4:集合中的布尔和整数(猜猜输出)

这段代码看起来完全正确,但它在生产环境上悄无声息地出了问题。


s = {True, 1, 1.0}
print(s)
print(len(s))

A. {True, 1, 1.0} 长度3B. {True} 1C. 报错

答案是 B。和字典键一样,集合也用哈希值和 == 来判断元素是否重复。True == 1 == 1.0,所以集合认为它们是同一个元素,只保留第一个加入的。这个行为和字典键的逻辑完全一致,因为 set 底层就是用字典实现的(只有键没有值)。


# 如果需要区分,用字符串或元组包装
s = {('bool', True), ('int', 1), ('float', 1.0)}
print(len(s))  # 3

踩坑现场:统计不同类型的数据去重,发现数量总是比预期少。


坑 5:浮点数精度问题

这坑是经典中的经典,Python 面试里没有比它更高频的了。


print(0.1 + 0.2 == 0.3)
print(0.1 + 0.2)

你觉得输出是什么?想好了吗?

实际是:False 0.30000000000000004

这不是 Python 的 bug,是 IEEE 754 浮点数标准的特性。0.1 在二进制中是无限循环小数,存储时会有微小误差。几乎所有编程语言都有这个问题。

正确写法:

import math
print(math.isclose(0.1 + 0.2, 0.3))  # True

# 金融计算用 Decimal
from decimal import Decimal

踩坑现场:电商系统计算订单总价,偶尔出现一分钱的误差,被财务追着问。


好了,今天这 5 个就先聊到这里。代码里的坑数不清,一期一期慢慢说。

这些坑你都知道吗?评论区交流一下你的翻车经历。

下期预告:函数陷阱专场


关于作者

写了 10 年 Python,赶上了机器学习的热潮,又撞上了大模型的浪头,每次以为学明白了,行业又变了一次。不是什么大神,就是一个在互联网里摸爬滚打、把坑踩了个遍的老工人。还在写代码,还在折腾,还在想明白这个时代到底发生了什么。把自己踩过的坑、走过的弯路、看过的热闹,说给还在路上的人听。

关注「鲁叶的Python」,一起穿越迷茫期。

最新文章

随机文章