Python 核心数据类型

目录

  1. 一切皆对象与类型体系
  2. 数字类型
    • 2.1 整数 int
    • 2.2 浮点数 float
    • 2.3 复数 complex
    • 2.4 布尔类型 bool
    • 2.5 类型转换与算术运算
  3. 序列类型与通用操作
  4. 字符串 str
    • 4.1 字符串的不可变性
    • 4.2 常用方法
    • 4.3 格式化进阶:f-string 与格式规范
    • 4.4 编码与字节
  5. 列表 list
    • 5.1 列表的可变性
    • 5.2 常用方法
    • 5.3 列表推导式
    • 5.4 排序与自定义关键字
  6. 元组 tuple
    • 6.1 不可变序列
    • 6.2 单元素元组与解包
    • 6.3 命名元组 namedtuple
  7. 字典 dict
    • 7.1 映射类型
    • 7.2 常用方法
    • 7.3 字典推导式
    • 7.4 特殊字典:defaultdict, Counter, OrderedDict
  8. 集合 setfrozenset
    • 8.1 可变集合与不可变集合
    • 8.2 集合运算
    • 8.3 集合推导式
  9. 可变性与不可变性总结
  10. 综合示例与最佳实践

1. 一切皆对象与类型体系

在 Python 中,一切数据都是对象。数字、字符串、函数、类本身都是对象,都有类型(class)和方法。内置核心类型大致分为:

  • 数值类型int, float, complex
  • 布尔类型bool(是 int 的子类)
  • 序列类型str, list, tuple, bytes, bytearray
  • 映射类型dict
  • 集合类型set, frozenset
  • 特殊类型NoneTypeNone 是唯一实例)

了解每个类型的可变性(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.Decimalfractions.Fraction

2.3 复数 complex

c = 3 + 4j
print(c.real, c.imag)      # 3.0 4.0
print(abs(c))              # 5.0  (模)

2.4 布尔类型 bool

boolint 的子类,TrueFalse 实际上就是 10,但它们是单例对象。

print(True + True)          # 2
print(isinstance(True, int)) # True

在逻辑判断中,每个对象都有真值(truth value):None00.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 + s2s * n
  • 成员检查x in sx not in s
  • 长度len(s)
  • 最小/最大min(s), max(s)
  • 排序相关sorted(s) 返回新列表
  • 遍历for item in senumerate(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. 集合 setfrozenset

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 ...)),而非一次性生成所有数据。
  • 命名元组提升代码可读性。
  • 当需要一定功能的缺省值时,defaultdictdict.get() 更干净。

掌握核心数据类型是 Python 编程的基石,后续的函数式编程、面向对象编程和算法都建立在这些强大而灵活的内置容器之上。重复练习、多查阅官方文档,它们将成为你解决问题的利器。

更多推荐