3. Python核心数据类型
Python 核心数据类型
目录
- 一切皆对象与类型体系
- 数字类型
- 2.1 整数
int - 2.2 浮点数
float - 2.3 复数
complex - 2.4 布尔类型
bool - 2.5 类型转换与算术运算
- 2.1 整数
- 序列类型与通用操作
- 字符串
str- 4.1 字符串的不可变性
- 4.2 常用方法
- 4.3 格式化进阶:f-string 与格式规范
- 4.4 编码与字节
- 列表
list- 5.1 列表的可变性
- 5.2 常用方法
- 5.3 列表推导式
- 5.4 排序与自定义关键字
- 元组
tuple- 6.1 不可变序列
- 6.2 单元素元组与解包
- 6.3 命名元组
namedtuple
- 字典
dict- 7.1 映射类型
- 7.2 常用方法
- 7.3 字典推导式
- 7.4 特殊字典:defaultdict, Counter, OrderedDict
- 集合
set与frozenset- 8.1 可变集合与不可变集合
- 8.2 集合运算
- 8.3 集合推导式
- 可变性与不可变性总结
- 综合示例与最佳实践
1. 一切皆对象与类型体系
在 Python 中,一切数据都是对象。数字、字符串、函数、类本身都是对象,都有类型(class)和方法。内置核心类型大致分为:
- 数值类型:
int,float,complex - 布尔类型:
bool(是int的子类) - 序列类型:
str,list,tuple,bytes,bytearray - 映射类型:
dict - 集合类型:
set,frozenset - 特殊类型:
NoneType(None是唯一实例)
了解每个类型的可变性(mutable or immutable)和可哈希性(是否可作为字典键)对于正确编码至关重要。
2. 数字类型
2.1 整数 int
Python 整数是任意精度的,可以表示天文级数字,无溢出问题。
big = 2 ** 1000
print(big) # 一个 302 位的整数
print(type(big), big.bit_length()) # <class 'int'> 302
支持二进制 0b、八进制 0o、十六进制 0x 字面量。
2.2 浮点数 float
对应 C 的 double,遵循 IEEE 754 双精度,存在精度误差。
print(0.1 + 0.2) # 0.30000000000000004
print(0.1 + 0.2 == 0.3) # False
需要高精度计算时使用 decimal.Decimal 或 fractions.Fraction。
2.3 复数 complex
c = 3 + 4j
print(c.real, c.imag) # 3.0 4.0
print(abs(c)) # 5.0 (模)
2.4 布尔类型 bool
bool 是 int 的子类,True 和 False 实际上就是 1 和 0,但它们是单例对象。
print(True + True) # 2
print(isinstance(True, int)) # True
在逻辑判断中,每个对象都有真值(truth value):None、0、0.0、空序列/映射、False 等为假;其他为真。
2.5 类型转换与算术运算
int(x),float(x),complex(x)转换- 运算符:
+ - * / // % **,优先级:**>* / // %>+ - - 增强赋值:
+=,-=等
a = 10
a //= 3 # a = a // 3 → 3
3. 序列类型与通用操作
序列类型(str, list, tuple, range, bytes)共享如下操作:
- 索引:
s[i]支持负数索引,-1为最后一个元素 - 切片:
s[i:j:step],返回新序列 - 拼接与重复:
s1 + s2,s * n - 成员检查:
x in s,x not in s - 长度:
len(s) - 最小/最大:
min(s),max(s) - 排序相关:
sorted(s)返回新列表 - 遍历:
for item in s,enumerate(s)获取索引
s = "Hello"
print(s[-1]) # 'o'
print(s[1:4]) # 'ell'
print(s[::-1]) # 'olleH'
4. 字符串 str
4.1 字符串的不可变性
字符串是不可变对象:一旦创建,内容不可修改。任何“修改”操作都会返回新字符串。
s = "hello"
s[0] = 'H' # TypeError: 'str' object does not support item assignment
s = 'H' + s[1:] # 创建新字符串 "Hello"
4.2 常用方法
s = " Hello, World! "
print(s.strip()) # 'Hello, World!'
print(s.lower()) # ' hello, world! '
print(s.replace("World", "Python")) # ' Hello, Python! '
print(s.split(',')) # [' Hello', ' World! ']
print(" ".join(['Hello','World'])) # 'Hello World'
# 查找
print(s.find("World")) # 8 (找不到返回 -1)
print(s.startswith(" H")) # True
4.3 格式化进阶:f-string 与格式规范
f-string 内嵌表达式,可应用格式描述符:
pi = 3.14159
print(f"Pi ≈ {pi:.2f}") # Pi ≈ 3.14
name = "Alice"
print(f"{name:>10}") # 右对齐,宽度10 ' Alice'
print(f"{1000000:,}") # 千分位 1,000,000
# 日期时间格式化
import datetime
now = datetime.datetime.now()
print(f"{now:%Y-%m-%d %H:%M:%S}")
4.4 编码与字节
字符串与字节的转换:
s = "你好"
b = s.encode('utf-8') # b'\xe4\xbd\xa0\xe5\xa5\xbd'
print(b.decode('utf-8')) # '你好'
bytes 是不可变字节序列,bytearray 是可变的。
5. 列表 list
5.1 列表的可变性
列表是可变序列,可以原地修改。
lst = [1, 2, 3]
lst[0] = 100 # [100, 2, 3]
lst.append(4) # [100, 2, 3, 4]
lst += [5, 6] # 扩展
5.2 常用方法
lst = [1, 2, 3]
lst.extend([4, 5]) # 扩展
lst.insert(1, 10) # 在索引1前插入10
lst.remove(2) # 删除第一个值为2的元素
popped = lst.pop(0) # 按索引删除并返回
lst.sort(reverse=True) # 原地排序
lst.reverse() # 原地反转
# 拷贝注意
a = [1, 2, [3, 4]]
b = a.copy() # 浅拷贝
b[2][0] = 99
print(a) # [1, 2, [99, 4]] 嵌套列表受影响
需要完全独立拷贝时使用 copy.deepcopy。
5.3 列表推导式
提供简洁生成列表的方式。
squares = [x**2 for x in range(5)] # [0,1,4,9,16]
evens = [x for x in range(10) if x % 2 == 0] # [0,2,4,6,8]
pairs = [(x, y) for x in [1,2] for y in [3,4]] # 可嵌套
5.4 排序与自定义关键字
words = ['apple', 'banana', 'cherry', 'date']
words.sort(key=len) # 按长度排序
words.sort(key=lambda w: w[-1]) # 按最后一个字母
# sorted 返回新列表
new = sorted(words, key=str.lower)
sort() 方法只用于列表;sorted() 可处理任何可迭代对象,返回新列表。
6. 元组 tuple
6.1 不可变序列
元组创建后不可修改,因此可以作为字典键。
t = (1, 2, 3)
print(t[0]) # 1
t[0] = 10 # TypeError
# 但是元组内的可变元素可以被修改
t = (1, [2, 3])
t[1].append(4) # t = (1, [2, 3, 4])
因为元组不可变,所以它们天然支持哈希(只要内部所有元素可哈希)。
6.2 单元素元组与解包
- 单元素元组需加逗号:
single = (1,)或single = 1, - 解包是元组的常见用法:
a, b = b, a # 交换
point = (10, 20)
x, y = point
first, *middle, last = [1, 2, 3, 4, 5] # first=1, middle=[2,3,4], last=5
6.3 命名元组 namedtuple
来自 collections,为元组元素赋予名称,兼顾不可变性和可读性。
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print(p.x, p.y) # 10 20
print(p[0]) # 10
# _replace 方法返回新元组
p2 = p._replace(x=30)
7. 字典 dict
7.1 映射类型
字典存储键值对,键必须不可变(可哈希),值任意。Python 3.7+ 保证插入顺序。
d = {"name": "Alice", "age": 25}
print(d["name"]) # 'Alice'
d["age"] = 26 # 更新
d["city"] = "NY" # 新增
7.2 常用方法
d.get("name", "Unknown") # 安全获取
d.keys(), d.values(), d.items() # 视图对象
d.update({"age": 30, "gender": "F"}) # 合并
d.pop("city") # 删除并返回值
d.popitem() # 移除最后一项(3.7前任意)
d.setdefault("score", 0) # 若不存在则设为0并返回0
7.3 字典推导式
squares = {x: x**2 for x in range(5)} # {0:0, 1:1, 2:4, 3:9, 4:16}
字典推导式同样支持条件过滤。
7.4 特殊字典:defaultdict, Counter, OrderedDict
from collections import defaultdict, Counter, OrderedDict
# defaultdict: 访问不存在的键时自动创建默认值
dd = defaultdict(list)
dd['a'].append(1) # 无需初始化空列表
# Counter: 计数
cnt = Counter("abracadabra")
print(cnt.most_common(3)) # [('a', 5), ('b', 2), ('r', 2)]
# OrderedDict 在 3.7+ 中普通 dict 已有序,但仍保留(比如 move_to_end 等操作)
od = OrderedDict()
od['z'] = 1
od['a'] = 2
od.move_to_end('z') # 移到末尾
8. 集合 set 与 frozenset
8.1 可变集合与不可变集合
set可变,不保证顺序,元素唯一且必须可哈希。frozenset不可变,可哈希,可作为字典键或放入集合。
s = {1, 2, 3, 3} # {1, 2, 3} 自动去重
fs = frozenset([1, 2, 3])
d = {fs: "value"} # 允许
8.2 集合运算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # 并集 {1,2,3,4,5,6}
print(a & b) # 交集 {3,4}
print(a - b) # 差集 {1,2}
print(a ^ b) # 对称差 {1,2,5,6}
# 方法
a.add(5)
a.discard(2) # 删除,不存在不报错
a.remove(2) # 删除,不存在报 KeyError
8.3 集合推导式
{x for x in 'abracadabra' if x not in 'abc'} # {'r', 'd'}
9. 可变性与不可变性总结
| 类型 | 可变性 | 可哈希(可作为键) | 备注 |
|---|---|---|---|
int, float, complex |
不可变 | 是 | |
bool |
不可变 | 是 | |
str |
不可变 | 是 | |
bytes |
不可变 | 是 | |
tuple |
不可变 | 是(元素全可哈希) | 包含可变元素则不可哈希 |
list |
可变 | 否 | |
dict |
可变 | 否 | 键必须可哈希 |
set |
可变 | 否 | |
frozenset |
不可变 | 是 |
理解变与不变对于函数参数传递、拷贝、性能优化至关重要。
10. 综合示例与最佳实践
下面通过一个简单的任务展示各种类型协同工作:统计一段文本中每个单词出现的次数,并按频率排序。
from collections import Counter
import re
text = "Python is great, Python is dynamic, Python is fun!"
# 小写并分割
words = re.findall(r'\w+', text.lower()) # ['python', 'is', 'great', 'python', 'is', 'dynamic', 'python', 'is', 'fun']
word_count = Counter(words)
print(word_count) # Counter({'python': 3, 'is': 3, 'great': 1, 'dynamic': 1, 'fun': 1})
# 按频率排序
sorted_counts = sorted(word_count.items(), key=lambda x: x[1], reverse=True)
for word, count in sorted_counts:
print(f"{word:10}: {count}") # 格式化对齐
最佳实践提醒:
- 使用
[]和{}字面量分别创建列表/字典,避免调用list()或dict()除非进行拷贝或转换。 - 使用集合来进行成员检查和去重,效率远高于列表。
- 对于大型数据,优先考虑使用生成器表达式(
(x for x ...)),而非一次性生成所有数据。 - 命名元组提升代码可读性。
- 当需要一定功能的缺省值时,
defaultdict比dict.get()更干净。
掌握核心数据类型是 Python 编程的基石,后续的函数式编程、面向对象编程和算法都建立在这些强大而灵活的内置容器之上。重复练习、多查阅官方文档,它们将成为你解决问题的利器。
更多推荐
所有评论(0)