欢迎光临
我们一直在努力

Python array数组与bytearray字节数组详解

Python array数组与bytearray字节数组详解

  • 一、Python array数组详解
    • 1、核心特性
    • 2、类型码(Typecode)
    • 3、创建数组
    • 4、核心操作
      • (1)、 增删元素
      • (2)、 访问与切片
      • (3)、 数值计算
    • 5、高效内存管理
    • 6、与列表 (`list`) 对比*
    • 7、实战场景
      • (1)、 处理大型数据集
      • (2) 、文件 I/O 加速
      • (3) 、科学计算桥梁
    • 8、注意事项
    • 总结
  • 二、Python bytearray字节数组详解
    • 1、核心特性
    • 2、创建方式
    • 3、常用操作
    • 4、 关键方法
    • 5、 使用场景
    • 6、与 bytes 的对比
    • 7、注意事项
  • 三、代码示例
    • 1、array
    • 2、bytearray

在这里插入图片描述

一、Python array数组详解

array.array 是 Python 标准库中提供的高效数值数组实现,专为存储同质数据类型设计。与列表 (list) 相比,它在内存占用和数值操作性能上具有显著优势,尤其适合处理大规模数值数据。


1、核心特性

  • 类型限定:所有元素必须是相同类型(通过类型码指定)。
  • 内存连续:数据在内存中连续存储,减少内存碎片。
  • 高效操作:支持快速的数值计算和缓冲区协议(如 memoryview)。
  • C 语言兼容:可直接与 C/C++ 数组交互。

2、类型码(Typecode)

类型码定义数组元素的数据类型,常用类型码如下:

类型码C 类型Python 类型最小字节数
'b' signed char int 1
'B' unsigned char int 1
'i' signed int int 2
'I' unsigned int int 2
'f' float float 4
'd' double float 8

3、创建数组

import array

# 创建空数组(指定类型码)
arr1 = array.array('i') # 有符号整数数组

# 用可迭代对象初始化
arr2 = array.array('f', [1.5, 2.8, 3.2]) # 浮点数数组


4、核心操作

(1)、 增删元素

arr = array.array('i', [10, 20, 30])

# 追加元素
arr.append(40) # [10, 20, 30, 40]

# 插入元素
arr.insert(1, 15) # [10, 15, 20, 30, 40]

# 删除元素
arr.pop(2) # 移除索引2的元素(返回20),数组变为 [10, 15, 30, 40]
arr.remove(30) # 移除第一个值为30的元素,结果 [10, 15, 40]

(2)、 访问与切片

# 索引访问
print(arr[0]) # 输出: 10

# 切片操作(返回新数组)
sub_arr = arr[1:3] # 子数组 [15, 40]

# 修改元素
arr[2] = 99 # 数组变为 [10, 15, 99]

(3)、 数值计算

# 向量加法(需同类型)
arr1 = array.array('i', [1, 2, 3])
arr2 = array.array('i', [4, 5, 6])
result = array.array('i', [a + b for a, b in zip(arr1, arr2)])
# 结果: [5, 7, 9]


5、高效内存管理

  • 内存视图 (memoryview) 直接操作底层内存缓冲区:mv = memoryview(arr)
    mv[1] = 88 # 直接修改内存,arr[1] 变为 88
  • 字节表示 (tobytes() / frombytes()) 与二进制数据互转:data = arr.tobytes() # 转为字节串
    new_arr = array.array('i')
    new_arr.frombytes(data) # 从字节串恢复

6、与列表 (list) 对比*

特性array.arraylist
数据类型 同质(固定类型码) 异构(任意对象)
内存占用 低(连续内存) 高(指针+对象)
数值操作 极快(直接操作内存) 较慢(需类型检查)
功能扩展 有限(专注数值) 丰富(支持任意操作)
适用场景 大规模数值计算、I/O 密集型任务 通用数据容器

7、实战场景

(1)、 处理大型数据集

# 生成100万个浮点数(比列表节省约40%内存)
data = array.array('d', [i * 0.1 for i in range(1_000_000)])

(2) 、文件 I/O 加速

# 写入二进制文件
with open('data.bin', 'wb') as f:
data.tofile(f) # 比逐元素写入快10倍+

# 从文件读取
new_data = array.array('d')
with open('data.bin', 'rb') as f:
new_data.fromfile(f, 1_000_000) # 精确读取指定数量元素

(3) 、科学计算桥梁

# 转为 NumPy 数组(零拷贝)
import numpy as np
np_arr = np.frombuffer(data, dtype=np.float64)


8、注意事项

  • 类型严格性: 插入错误类型会引发 TypeError:arr = array.array('i')
    arr.append(3.14) # TypeError: integer argument expected, got float
  • 性能权衡: 频繁增删元素时性能低于列表(需整体内存重分配)。
  • 类型码选择: 例如 'i' 在多数平台是4字节(非2字节),需用 array.itemsize 验证:print(array.array('i').itemsize) # 输出: 4(字节)

  • 总结

    array.array 是 Python 中处理数值密集型任务的轻量级工具,适用于:

    • 需要极致内存效率的场景
    • 大规模数值数据存储/读取
    • 与底层 C 库交互的桥梁

    二、Python bytearray字节数组详解

    bytearray 是 Python 中用于处理可变二进制数据的内置类型,本质是一个可变的字节序列。每个元素是 0~255 的整数,表示一个字节。与不可变的 bytes 类型相比,bytearray 支持就地修改。

    1、核心特性

    • 可变性:支持索引赋值、切片修改等操作
    • 序列类型:支持迭代、切片、长度查询等序列操作
    • 整数存储:元素是整数(如 72),但打印显示对应 ASCII 字符(如 H)
    • 内存视图:通过 memoryview 支持零拷贝缓冲协议

    2、创建方式

    # 空字节数组
    ba1 = bytearray()

    # 指定长度(初始化为0)
    ba2 = bytearray(5) # → bytearray(b'\\x00\\x00\\x00\\x00\\x00')

    # 从可迭代对象
    ba3 = bytearray([65, 66, 67]) # → bytearray(b'ABC')

    # 从bytes转换
    ba4 = bytearray(b'Python') # → bytearray(b'Python')

    # 从字符串(需指定编码)
    ba5 = bytearray("你好", encoding='utf-8') # → bytearray(b'\\xe4\\xbd\\xa0\\xe5\\xa5\\xbd')

    3、常用操作

    ba = bytearray(b'Hello')

    # 索引访问/修改
    print(ba[0]) # → 72 (ASCII 'H')
    ba[1] = 97 # 修改为 'a' → bytearray(b'Hallo')

    # 切片操作
    print(ba[:2]) # → bytearray(b'Ha')
    ba[2:4] = b'xx' # → bytearray(b'Haxxo')

    # 添加数据
    ba.append(33) # 添加 '!' → bytearray(b'Haxxo!')
    ba.extend(b'!!') # → bytearray(b'Haxxo!!!')

    # 查找/统计
    print(ba.find(b'x')) # → 2
    print(ba.count(b'!')) # → 3

    # 类型转换
    str_data = ba.decode('utf-8') # 解码为字符串
    bytes_data = bytes(ba) # 转为不可变bytes

    4、 关键方法

    方法描述示例
    append(x) 添加字节(x为0-255整数) ba.append(10)
    extend(iterable) 扩展字节序列 ba.extend([13, 10])
    insert(i, x) 在位置i插入字节x ba.insert(0, 0xFF)
    pop([i]) 移除并返回指定位置字节 ba.pop()
    remove(x) 移除首个值为x的字节 ba.remove(65)
    reverse() 反转字节序列 ba.reverse()
    decode(encoding) 解码为字符串 ba.decode('utf-8')

    5、 使用场景

  • 二进制协议处理:修改网络数据包packet = bytearray(b'\\x01\\x02\\x03\\x04')
    packet[2] = 0xFF # 修改协议字段
  • 文件编辑:修改二进制文件部分内容with open('file.bin', 'rb+') as f:
    data = bytearray(f.read())
    data[100:120] = b'NEW_DATA'
    f.seek(0)
    f.write(data)
  • 编码转换中间层:处理多字节编码text = "你好世界"
    ba = bytearray(text.encode('gbk'))
    ba[0:2] = b'\\xCC\\xDD' # 修改中文字符
    modified = ba.decode('gbk')
  • 6、与 bytes 的对比

    特性bytearraybytes
    可变性 ✅ 支持原地修改 ❌ 不可变
    内存效率 修改时可能触发复制 更高效
    创建开销 略高(需可变结构) 低
    哈希支持 ❌ 不可哈希 ✅ 可哈希
    使用场景 需修改的二进制数据 只读二进制数据

    7、注意事项

    • 类型转换:直接打印时显示为 bytearray(b'…'),实际是整数序列
    • 边界检查:赋值超出 0-255 会触发 ValueError
    • 编码处理:字符串转换需显式指定编码(默认 UTF-8)
    • 性能优化:频繁修改时优先考虑 memoryview 避免复制

    三、代码示例

    1、array

    # 必须先导入 array 模块
    from array import array

    # ======================================
    # 1. 创建 array(指定类型码 + 初始化数据)
    # 类型码(最常用):
    # 'b'=有符号char, 'B'=无符号char
    # 'i'=有符号int, 'I'=无符号int
    # 'f'=float, 'd'=double
    # ======================================
    # 整数数组
    arr_int = array('i', [10, 20, 30, 40, 50])
    # 浮点数组
    arr_float = array('f', [1.1, 2.2, 3.3, 4.4])
    # 空数组
    arr_empty = array('i')
    # 从列表生成
    lst = [1, 3, 5, 7]
    arr_from_list = array('i', lst)

    print("=== 1. 创建数组 ===")
    print("整数数组 arr_int:", arr_int)
    print("浮点数组 arr_float:", arr_float)
    print("空数组 arr_empty:", arr_empty)
    print("从列表创建:", arr_from_list)
    print("-" * 60)

    # ======================================
    # 2. 核心属性:类型、长度、占用内存
    # ======================================
    print("=== 2. 数组属性 ===")
    print("数组类型码:", arr_int.typecode) # 存储的类型
    print("每个元素字节数:", arr_int.itemsize) # 单个元素大小
    print("数组长度:", len(arr_int)) # 元素个数
    print("数组地址信息:", arr_int.buffer_info())
    print("-" * 60)

    # ======================================
    # 3. 索引、切片(和 list 完全一样)
    # ======================================
    print("=== 3. 索引 & 切片 ===")
    print("第0个元素:", arr_int[0])
    print("最后1个元素:", arr_int[–1])
    print("切片 [1:4]:", arr_int[1:4])
    print("倒序:", arr_int[::–1])

    # 修改元素
    arr_int[0] = 999
    print("修改后数组:", arr_int)
    print("-" * 60)

    # ======================================
    # 4. 添加元素(append、extend、insert)
    # ======================================
    print("=== 4. 添加元素 ===")
    arr_int.append(60) # 末尾添加1个
    arr_int.extend([70, 80]) # 批量添加
    arr_int.insert(2, 25) # 指定位置插入
    print("添加后数组:", arr_int)
    print("-" * 60)

    # ======================================
    # 5. 删除元素(remove、pop、del)
    # ======================================
    print("=== 5. 删除元素 ===")
    arr_int.remove(30) # 删除指定值
    del arr_int[1] # 删除指定索引
    pop_val = arr_int.pop() # 删除末尾并返回
    print("删除后数组:", arr_int)
    print("弹出的值:", pop_val)
    print("-" * 60)

    # ======================================
    # 6. 查找、统计、排序
    # ======================================
    print("=== 6. 查找 & 统计 & 排序 ===")
    print("元素40的索引:", arr_int.index(40))
    print("元素25出现次数:", arr_int.count(25))

    # 排序(array 没有 sort 方法,转 list 排序)
    sorted_arr = array('i', sorted(arr_int))
    print("排序后数组:", sorted_arr)
    print("-" * 60)

    # ======================================
    # 7. 遍历数组
    # ======================================
    print("=== 7. 遍历数组 ===")
    for num in arr_int:
    print(num, end=" ")
    print("\\n" + "-" * 60)

    # ======================================
    # 8. 与 list 互相转换
    # ======================================
    print("=== 8. array ↔ list ===")
    arr = array('i', [1,2,3])
    lst_new = arr.tolist() # 数组 → 列表
    print("数组转列表:", lst_new, type(lst_new))

    arr_new = array('i', lst_new) # 列表 → 数组
    print("列表转数组:", arr_new, type(arr_new))
    print("-" * 60)

    # ======================================
    # 9. 二进制文件读写(array 核心优势)
    # ======================================
    print("=== 9. 文件读写(二进制) ===")
    # 写入文件
    with open("array_data.bin", "wb") as f:
    arr_int.tofile(f)

    # 从文件读取
    read_arr = array('i')
    with open("array_data.bin", "rb") as f:
    read_arr.fromfile(f, 5) # 读取5个元素

    print("从文件读取的数组:", read_arr)
    print("-" * 60)

    # ======================================
    # 10. 重要规则:只能存同类型数据
    # ======================================
    print("=== 10. 类型限制 ===")
    try:
    arr_int.append("字符串") # 报错!只能存数字
    except TypeError as e:
    print("错误:只能存同类型数值 →", e)

    try:
    arr_int.append(3.14) # 报错!int 数组不能存 float
    except TypeError as e:
    print("错误:类型不匹配 →", e)
    print("-" * 60)

    运行结果:

    "D:\\user\\01417804\\桌面\\新建文件夹 (2)\\.venv\\Scripts\\python.exe" "D:\\user\\01417804\\桌面\\新建文件夹 (2)\\main.py"
    === 1. 创建数组 ===
    整数数组 arr_int: array('i', [10, 20, 30, 40, 50])
    浮点数组 arr_float: array('f', [1.100000023841858, 2.200000047683716, 3.299999952316284, 4.400000095367432])
    空数组 arr_empty: array('i')
    从列表创建: array('i', [1, 3, 5, 7])
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    === 2. 数组属性 ===
    数组类型码: i
    每个元素字节数: 4
    数组长度: 5
    数组地址信息: (2216627144784, 5)
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    === 3. 索引 & 切片 ===
    第0个元素: 10
    最后1个元素: 50
    切片 [1:4]: array('i', [20, 30, 40])
    倒序: array('i', [50, 40, 30, 20, 10])
    修改后数组: array('i', [999, 20, 30, 40, 50])
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    === 4. 添加元素 ===
    添加后数组: array('i', [999, 20, 25, 30, 40, 50, 60, 70, 80])
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    === 5. 删除元素 ===
    删除后数组: array('i', [999, 25, 40, 50, 60, 70])
    弹出的值: 80
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    === 6. 查找 & 统计 & 排序 ===
    元素40的索引: 2
    元素25出现次数: 1
    排序后数组: array('i', [25, 40, 50, 60, 70, 999])
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    === 7. 遍历数组 ===
    999 25 40 50 60 70
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    === 8. array ↔ list ===
    数组转列表: [1, 2, 3] <class 'list'>
    列表转数组: array('i', [1, 2, 3]) <class 'array.array'>
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    === 9. 文件读写(二进制) ===
    从文件读取的数组: array('i', [999, 25, 40, 50, 60])
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    === 10. 类型限制 ===
    错误:只能存同类型数值 → 'str' object cannot be interpreted as an integer
    错误:类型不匹配 → 'float' object cannot be interpreted as an integer
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––

    进程已结束,退出代码为 0

    在这里插入图片描述

    2、bytearray

    # ==============================================
    # Python bytearray 完整使用示例
    # 特点:可变、二进制、元素 0~255、有序、可索引/切片
    # ==============================================

    # 1. 创建 bytearray 的 6 种方式
    print("===== 1. 创建 bytearray =====")
    ba1 = bytearray() # 空
    ba2 = bytearray(5) # 5 个 0x00 字节
    ba3 = bytearray([65, 66, 67, 97, 98]) # 从整数列表
    ba4 = bytearray(b"hello bytes") # 从 bytes
    ba5 = bytearray("中文测试", encoding="utf-8") # 字符串编码
    ba6 = bytearray("abc123", "utf-8")

    print("ba1 =", ba1)
    print("ba2 =", ba2)
    print("ba3 =", ba3)
    print("ba4 =", ba4)
    print("ba5 =", ba5)
    print("ba6 =", ba6)
    print("-" * 60)

    # 2. 核心属性:有序、可索引、可切片、可修改(最重要!)
    print("===== 2. 索引、切片、修改 =====")
    data = bytearray(b"python123")

    print("第0个元素:", data[0])
    print("最后元素:", data[–1])
    print("切片 [1:4]:", data[1:4])

    # 可修改!!!(bytes 做不到)
    data[0] = 80 # 把 'p' → 'P'
    data[1] = 89
    print("修改后:", data)
    print("-" * 60)

    # 3. 增删元素(append, extend, insert, pop, remove)
    print("===== 3. 增删操作 =====")
    ba = bytearray(b"abc")

    ba.append(100) # 末尾加一个字节
    ba.extend([49, 50, 51]) # 批量加
    ba.insert(1, 88) # 插入

    print("添加后:", ba)

    ba.pop() # 删除最后
    ba.remove(88) # 删除指定值
    print("删除后:", ba)
    print("-" * 60)

    # 4. 遍历 bytearray
    print("===== 4. 遍历 =====")
    for b in ba4:
    print(f"数值:{b} → 字符:{chr(b)}")
    print("-" * 60)

    # 5. 查找、替换、统计
    print("===== 5. 查找、替换、统计 =====")
    msg = bytearray(b"hello hello world")

    print("find hello:", msg.find(b"hello"))
    print("count hello:", msg.count(b"hello"))

    new_msg = msg.replace(b"hello", b"hi")
    print("替换后:", new_msg)
    print("-" * 60)

    # 6. 拼接、重复、长度
    print("===== 6. 运算 =====")
    a = bytearray(b"123")
    b = bytearray(b"abc")

    c = a + b
    print("拼接:", c)
    print("重复:", a * 2)
    print("长度:", len(c))
    print("-" * 60)

    # 7. 编码解码:str ↔ bytearray
    print("===== 7. 编码解码 =====")
    # 字符串 → bytearray
    s = "你好Python"
    ba_str = bytearray(s, "utf-8")
    print("编码后:", ba_str)

    # bytearray → 字符串
    s2 = ba_str.decode("utf-8")
    print("解码后:", s2)
    print("-" * 60)

    # 8. 与 bytes 互转
    print("===== 8. bytearray ↔ bytes =====")
    ba = bytearray(b"test")
    b = bytes(ba) # 转 bytes
    print("bytearray → bytes:", b, type(b))

    ba2 = bytearray(b) # bytes → bytearray
    print("bytes → bytearray:", ba2, type(ba2))
    print("-" * 60)

    # 9. 清空、判断
    print("===== 9. 清空 & 判断 =====")
    ba = bytearray(b"abc123")
    ba.clear()
    print("清空后:", ba)
    print("是否为空:", len(ba) == 0)
    print("-" * 60)

    # 10. 重要规则:元素必须 0~255
    print("===== 10. 数值范围限制 =====")
    try:
    ba = bytearray([300]) # 报错!超过 255
    except ValueError as e:
    print("错误:", e)
    print("-" * 60)

    # 11. 实用场景:修改二进制数据
    print("===== 11. 实战:修改二进制数据 =====")
    buffer = bytearray(b"\\x00\\x01\\x02\\x03\\x04")
    buffer[2] = 0xFF # 修改第3个字节
    print("修改后二进制:", buffer.hex()) # 转十六进制查看

    运行结果:

    "D:\\user\\01417804\\桌面\\新建文件夹 (2)\\.venv\\Scripts\\python.exe" "D:\\user\\01417804\\桌面\\新建文件夹 (2)\\main.py"
    ===== 1. 创建 bytearray =====
    ba1 = bytearray(b'')
    ba2 = bytearray(b'\\x00\\x00\\x00\\x00\\x00')
    ba3 = bytearray(b'ABCab')
    ba4 = bytearray(b'hello bytes')
    ba5 = bytearray(b'\\xe4\\xb8\\xad\\xe6\\x96\\x87\\xe6\\xb5\\x8b\\xe8\\xaf\\x95')
    ba6 = bytearray(b'abc123')
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 2. 索引、切片、修改 =====
    第0个元素: 112
    最后元素: 51
    切片 [1:4]: bytearray(b'yth')
    修改后: bytearray(b'PYthon123')
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 3. 增删操作 =====
    添加后: bytearray(b'aXbcd123')
    删除后: bytearray(b'abcd12')
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 4. 遍历 =====
    数值:104 → 字符:h
    数值:101 → 字符:e
    数值:108 → 字符:l
    数值:108 → 字符:l
    数值:111 → 字符:o
    数值:32 → 字符:
    数值:98 → 字符:b
    数值:121 → 字符:y
    数值:116 → 字符:t
    数值:101 → 字符:e
    数值:115 → 字符:s
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 5. 查找、替换、统计 =====
    find hello: 0
    count hello: 2
    替换后: bytearray(b'hi hi world')
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 6. 运算 =====
    拼接: bytearray(b'123abc')
    重复: bytearray(b'123123')
    长度: 6
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 7. 编码解码 =====
    编码后: bytearray(b'\\xe4\\xbd\\xa0\\xe5\\xa5\\xbdPython')
    解码后: 你好Python
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 8. bytearray ↔ bytes =====
    bytearray → bytes: b'test' <class 'bytes'>
    bytes → bytearray: bytearray(b'test') <class 'bytearray'>
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 9. 清空 & 判断 =====
    清空后: bytearray(b'')
    是否为空: True
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 10. 数值范围限制 =====
    错误: byte must be in range(0, 256)
    ––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
    ===== 11. 实战:修改二进制数据 =====
    修改后二进制: 0001ff0304

    进程已结束,退出代码为 0

    在这里插入图片描述

    在这里插入图片描述

    赞(0)
    未经允许不得转载:171主机测评 » Python array数组与bytearray字节数组详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址