器→工具, 编程语言

Python标准库之高效数组array

钱魏Way · · 18 次浏览

array 模块是 Python 标准库中的一个模块,用于创建和操作高效的数组。与列表相比,array 提供了一种更节省内存的方式来存储数据,尤其适用于存储大量数据或进行数值计算。array 模块中的数组存储了相同类型的元素,并提供了一些用于操作这些元素的方法。

当你开始编程之旅时,你一开始遇到的最基本的概念之一就是数组。如果你最近从另一种编程语言切换到 Python,那么你可能会惊讶地发现数组在 Python 中根本找不到作为内置语法构造的东西。你通常使用列表来代替数组,它与传统数组略有不同,而且更灵活。

array 模块是 Python 标准库中的一个模块,用于创建和操作高效的数组。与列表相比,array 提供了一种更节省内存的方式来存储数据,尤其适用于存储大量数据或进行数值计算。array 模块中的数组存储了相同类型的元素,并提供了一些用于操作这些元素的方法。

理解编程中的数组

有些开发人员将数组和 Python 的列表视为同义词。其他人则认为 Python 没有传统数组,就像C、C++或Java等语言中那样。

编程中的数组

为了更好地理解数组,我们有必要从理论的角度来看待它们。这将澄清一些基本术语,包括:

  • 抽象数据类型
  • 数据结构
  • 数据类型

抽象数据类型(Abstract Data Type,ADT)、数据结构和数据类型是计算机科学中三个密切相关但有区别的概念。它们在程序设计和软件工程中扮演着重要角色。以下是对这三个概念的详细介绍及其关系:

数据类型(Data Type)

  • 数据类型是编程语言中定义的一种属性,用于指定变量或常量可以存储的数据种类。常见的数据类型包括整数(int)、浮点数(float)、字符(char)、布尔值(boolean)等。
  • 数据类型定义了数据的取值范围、存储方式以及可以对其进行的操作。例如,整数类型通常支持加减乘除等算术操作。
  • 数据类型可以是原始的(如基本数据类型)或复杂的(如枚举类型、结构体等)。

抽象数据类型(Abstract Data Type,ADT)

  • 抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。ADT强调数据的逻辑行为而不是实现细节。
  • ADT提供了一种接口,通过该接口可以操作数据,但不涉及具体实现。例如,栈(Stack)作为ADT,提供了push、pop等操作,而不规定这些操作如何实现。
  • ADT的关键在于数据抽象,即隐藏具体实现细节,使得程序员可以关注于数据操作的逻辑层面。

数据结构(Data Structure)

  • 数据结构是计算机中数据存储和组织的具体实现方式。它不仅描述了数据的存储方式,还定义了操作这些数据的算法。
  • 常见的数据结构包括数组、链表、栈、队列、树、图、哈希表等。每种数据结构都有其优缺点和适用场景。
  • 数据结构的选择和实现会影响程序的性能和复杂性。例如,数组适合快速访问,而链表适合频繁插入和删除操作。

关系

  • ADT与数据类型:ADT可以被视为一种高级数据类型。数据类型是编程语言中基本的概念,而ADT是从抽象层面定义的一种高级数据类型。
  • ADT与数据结构:ADT定义了数据的抽象模型和操作接口,而数据结构则是ADT的具体实现。也就是说,ADT描述了“做什么”,而数据结构则描述了“怎么做”。
  • 数据结构与数据类型:数据结构可以使用基本数据类型来实现。数据类型提供了构建数据结构的基本单元,而数据结构则将这些基本单元组织成更复杂的形式以满足特定需求。

总之,数据类型、抽象数据类型和数据结构各有侧重,它们共同构成了计算机科学中处理和组织数据的理论基础。理解它们之间的关系有助于更好地设计和实现高效的程序。

重申这些术语的含义,抽象数据类型定义所需的语义,数据结构实现它们,数据类型将编程语言中的数据结构表示为内置的语法结构。

在某些情况下,您可以通过合并其他约束在现有 ADT 之上构建更具体的抽象数据类型。例如,您可以通过修改队列来构建堆栈,反之亦然。

ADT 列表不包含数组。这是因为数组是表示列表抽象数据类型的特定数据结构。列表 ADT 规定了数组必须支持哪些操作以及应该表现出哪些行为。列表抽象数据类型是值的线性集合,形成有序的元素序列。这些元素遵循特定的排列,这意味着每个元素相对于其他元素都有一个位置,由通常从零开始的数字索引标识。列表的长度可变但有限。它可能包含或不包含不同类型的值以及重复项。

列表抽象数据类型的接口类似于Python的list,通常包括以下操作:

列表 ADT Python 的list
通过索引获取元素 fruits[0]
在给定索引处设置元素 fruits[0] = “banana”
在给定索引处插入元素 fruits.insert(0, “banana”)
根据索引删除元素 fruits.pop(0),del fruits[0]
根据值删除元素 fruits.remove(“banana”)
删除所有元素 fruits.clear()
查找给定元素的索引 fruits.index(“banana”)
在右端附加一个元素 fruits.append(“banana”)
与另一个列表合并 fruits.extend(veggies),fruits + veggies
对元素进行排序 fruits.sort()
获取元素数量 len(fruits)
迭代元素 iter(fruits)
检查元素是否存在 “banana” in fruits

数组作为数据结构

为了以图形方式直观地展示传统的数组数据结构,请想象一系列大小相同的矩形框并排排列,每个矩形框都包含一个相同类型的不同值。例如,整数数组可能如下所示:

此数组有 7 个元素,索引从 0 到 6,全部为整数。请注意,其中一些值出现多次。

乍一看,这看起来就像Python list。毕竟,两者都代表前面介绍的列表抽象数据类型。数组数据结构的特殊之处在于一些独特的特性。特别是,数组必须是:

  • 同质:数组中的所有元素都具有相同的数据类型,从而使它们具有统一的大小。这与 Python 列表不同,后者允许包含混合类型的元素。
  • 连续:数组元素在计算机内存中彼此相邻,占据连续的内存空间块。数组的开头和结尾之间不允许有其他数据。这种布局与计算机内存的逻辑组织方式相对应。
  • 固定大小:由于其他数据可能紧跟在数组占用的内存块之后,因此扩展内存块会覆盖该数据,可能会导致严重错误或故障。因此,在为数组分配内存时,您必须预先知道其大小,并且不能稍后更改。

前两个特征使数组成为随机访问数据结构,让您可以立即检索任何给定索引处的元素,而无需遍历整个数组。当您知道数组中第一个元素的内存地址时,您可以通过应用简单的数学公式来计算所需元素的地址:

$$A_i = A_0 + {i} \times {size}$$

要查找数组中索引i处元素的内存地址$A_i $,您可以取数组的地址(该地址与索引初始处的第一个元素$A_0$的地址相同),然后添加偏移量。由于所有元素的大小都相同,因此您可以通过将目标索引i乘以单个元素的大小(以字节为单位)来获得内存地址偏移量。

只要所有元素的大小相同且彼此相邻,此公式就有效。这种内存布局的缺点是数组的大小是固定的,当您想添加、插入或删除元素时,这一点就会变得明显。但是,您只能通过创建另一个数组、将现有元素复制到其中并忽略旧数组来模拟调整大小。因此,您最终会频繁地向操作系统请求更大的内存块,并且浪费时间将数据从一个地方移动到另一个地方。这就是纯数组插入和删除效率低下的原因。

缓解此限制的一种方法是,在数组顶部构建一个抽象,该抽象会积极分配超出必要范围的内存,并根据数组的容量跟踪当前元素数量。当底层数组已满时,您可以重新分配数据并将其复制到更大的数组中。这大致就是 Python list在底层为您处理动态调整大小所做的工作。那么类型相同但大小可变的元素(例如字符串)怎么样?

字符串在计算机内存中可以有几种表示形式。例如,长度前缀表示会分配一个额外的字节来编码后面的字符数。另一种流行的表示形式是以空字符结尾的字符串,它本质上是一个以特殊标记值(称为空字符)结尾的字节数组。使用这种表示形式,您可以创建一个指向字符串的指针数组

上面描述的数组由指针或数字地址组成,每个指针都指示给定字符串开始的特定内存区域。尽管各个元素的大小可能不同,并且分散在计算机内存的各个角落,但它们对应的指针都是大小统一的纯整数,可以放入数组中。

事实证明,数组数据结构并不是实现列表抽象数据类型的唯一方法。接下来,您将了解一种流行的替代方案——链表。

数组与链表

到目前为止,您知道计算机科学中的列表是一种抽象数据类型,而数组是其具体实现之一。但为什么您想要有多种实现,以及如何知道要使用哪一种?

选择给定的数据结构对于性能内存效率至关重要。大多数数据结构在两者之间提供权衡,并且它们通常会为某些操作提供更好的时间空间复杂度,而牺牲其他操作。因此,您应该始终根据要解决的特定问题的要求选择合适的数据结构。

例如,您可以使用数组或链接列表实现列表抽象数据类型。两者都是元素序列,但数组更适合涉及频繁查找的场景,而当您预计有大量插入或删除操作时,链接列表会更好用。

数组和链表是两种基本的数据结构,各有其特点和适用场景。

数组

  • 定义: 数组是一种线性数据结构,由一组相同类型的元素按顺序排列而成。
  • 特点:
    • 固定大小: 数组在创建时需要指定大小,且大小固定。
    • 快速访问: 由于数组元素在内存中是连续存储的,可以通过索引快速访问任意元素,时间复杂度为 O(1)。
    • 插入和删除: 在数组中插入或删除元素需要移动其他元素,平均时间复杂度为 O(n)。
    • 内存使用: 数组在内存中是连续分配的,因此可能需要预留足够的连续内存空间。

链表

  • 定义: 链表是一种线性数据结构,由一组节点组成,每个节点包含数据和一个指向下一个节点的引用。
  • 种类:
    • 单链表: 每个节点只指向下一个节点。
    • 双链表: 每个节点有两个引用,分别指向前一个和后一个节点。
    • 循环链表: 链表的最后一个节点指向第一个节点,形成一个环。
  • 特点:
    • 动态大小: 链表不需要预先定义大小,可以根据需要动态增长或缩减。
    • 顺序访问: 由于节点不连续存储,访问某个节点需要从头开始遍历,时间复杂度为 O(n)。
    • 插入和删除: 在链表中插入或删除节点不需要移动其他节点,只需调整指针,时间复杂度为 O(1)。
    • 内存使用: 链表的节点可以分散在内存的不同位置,不需要连续内存空间,但每个节点需要额外的存储空间来保存指针。

选择依据

  • 如果需要频繁访问元素,且元素数量固定,数组是更好的选择。
  • 如果需要频繁插入和删除操作,且元素数量变化不定,链表更为适合。

Python 中的数组

尽管 Python list表示列表抽象数据类型,但其实现并不是典型的数组或链接列表。当您查看CPython 源代码时,您会发现底层PyListObject是指向对象的动态指针数组,这使得 Python list能够结合这两种数据结构的优点。它经过巧妙优化,可确保在大多数情况下快速查找和插入。Python 将前面概述的保存指向字符串的指针数组的想法更进了一步。它通过保留有关从内部数组指向的值的数据类型的额外信息来实现这一点。这使得 Python list能够存储任意类型的异构元素。另一方面,这和过度分配使得 Python 的list内存效率低于 C 等低级编程语言中常见的经典数组。

Python 的 list 类型是一种非常灵活的数据结构,尽管在名称上与“链表”相似,但其实现和特性更接近于动态数组。以下是 Python list 与数组和链表的关系及区别:

Python List 与数组的关系

  • 底层实现:
    • Python 的list 在底层是通过动态数组实现的。这意味着它在内存中是连续存储的,支持快速的索引访问。
  • 动态调整大小:
    • 与传统的固定大小数组不同,Python 的list 可以动态调整大小。当列表需要扩展时,Python 会自动分配更大的内存块并将元素复制到新位置。
  • 访问和性能:
    • 由于底层是数组,list可以通过索引进行 O(1) 时间复杂度的快速访问。
    • 插入和删除操作的平均时间复杂度为 O(n),特别是在列表的开头或中间进行这些操作时。
  • 多样性:
    • 与许多语言中的数组不同,Python 的list 可以存储不同类型的数据,而不仅限于一种数据类型。

Python List 与链表的关系

  • 内存布局:
    • 链表的节点在内存中不必是连续的,每个节点包含数据和指向下一个节点的指针。而 Python 的list 是基于连续的内存块。
  • 插入和删除:
    • 在链表中,插入和删除元素只需调整指针,通常是 O(1) 的操作(假设已经找到插入或删除的位置)。
    • 在 Python 的list 中,插入和删除元素通常需要移动其他元素,导致 O(n) 的时间复杂度。
  • 访问速度:
    • 链表需要顺序访问节点,因此访问某个元素的时间复杂度为 O(n)。
    • Python 的list 可以通过索引进行 O(1) 的直接访问。
  • 使用场景:
    • 链表适合需要频繁插入和删除的场景。
    • Python 的list 适合需要快速访问和遍历的场景。

总结

  • Python 的list 结合了数组和链表的一些特性,但在实现上更接近于动态数组。
  • 对于需要高效插入和删除的操作,特别是在大型数据集的中间,链表可能更合适。
  • 对于需要快速随机访问的操作,Python 的list 提供了很好的性能。
  • Python 也有其他数据结构,如deque,它提供了高效的双端插入和删除操作,适合某些特定场景。

总而言之,Python 内部依赖数组数据结构,但不会直接向您展示它。在 Python 中,最接近数组的是标准库array或NumPy 的 ndarray数据类型。然而,它们都没有提供真正的数组,因为它们只能保存数值

Python 的array模块

Python 中的array模块定义了一个高效的数组数据结构,其元素仅限于少数几种数字类型。因此,您将无法使用此模块创建任意数据类型(如字符串或自定义对象)的通用数组。不过,您可以使用它紧凑地表示大型数据集,以实现高性能数字运算。

Python array与C array的区别

Python中的array模块和C语言中的数组虽然都用于存储元素的集合,但它们之间存在一些关键的区别。以下是它们在特性、使用方式和功能上的比较:

Python array 模块

  • 动态性:
    • Python的array模块提供的数组是动态的,可以在运行时调整大小。这与Python列表相似,但只限于存储相同类型的元素。
    • 支持通过方法来增加或删除元素,例如append()、extend()等。
  • 类型安全:
    • Python数组需要指定存储的数据类型,使用类型码来定义(例如,’i’表示整数,’f’表示浮点数)。
    • 在数组中只能存储同一类型的数据,且可以通过类型码进行类型检查。
  • 内置方法:
    • 提供了一些用于数组操作的内置方法,如append()、remove()、pop()等。
  • 内存管理:
    • 由Python的内存管理机制处理,不需要手动分配或释放内存。
  • 错误处理:
    • 提供了丰富的错误处理机制和异常类型,帮助开发者在运行时捕获和处理错误。

C语言中的数组

  • 静态性:
    • C语言中的数组是静态的,其大小在编译时确定,不能在运行时动态调整。
    • 一旦分配,数组的大小是固定的,除非使用动态内存分配(如malloc)来创建数组。
  • 类型和大小限制:
    • 数组元素的类型在声明时确定,且必须是同一类型。
    • 数组的大小需要在编译时指定(对于静态数组),使用动态内存分配时可以在运行时指定。
  • 内存管理:
    • C语言中的数组直接使用内存地址进行存储,开发者需要手动管理内存。
    • 对于动态分配的数组,开发者需要使用free()来释放内存。
  • 操作灵活性:
    • C数组没有内置的方法来增加或删除元素,开发者需要手动管理数组内容。
    • 对于复杂的操作(如插入、删除),需要自己实现逻辑。
  • 性能:
    • 由于C语言的低级别特性,数组操作通常比Python更高效,特别是在需要处理大量数据时。

总结

  • 动态 vs 静态: Python的array模块提供了动态数组,适合需要在运行时调整大小的应用;C语言的数组通常是静态的,适合固定大小的数据集。
  • 内存管理: Python的数组由解释器管理内存,而C语言要求开发者自己管理内存,这使得C更灵活但也更容易出错。
  • 功能性: Python的数组提供了更高级的功能和更简单的接口,而C语言的数组则提供了更接近硬件的操作,适合需要高性能的场合。

Python array与NumPy的ndarray的区别

Python中的array模块和NumPy的ndarray(N-dimensional array)都是用于处理数组的工具,但它们之间存在显著的区别。以下是对这两者的详细比较:

Python array 模块

  • 基本功能:
    • array模块提供了一种基本的数组类型,类似于C语言中的数组。
    • 用于存储相同类型的基本数据(如整数、浮点数)。
  • 数据类型限制:
    • 数组中的所有元素必须是同一数据类型,数据类型通过类型码指定(例如,’i’表示整数,’f’表示浮点数)。
  • 功能和性能:
    • 提供的功能相对简单,主要用于存储和操作基本类型的数据。
    • 在处理小规模数据时,性能比Python内置的列表稍高,但不如NumPy。

NumPy ndarray

  • 高级功能:
    • ndarray是NumPy库的核心数据结构,支持多维数组和大量的数学、统计运算。
    • 非常适合处理大规模的数值数据和进行复杂的数值计算。
  • 多样的数据类型:
    • 支持多种数据类型,包括整数、浮点数、复数、布尔值等,提供了更高的灵活性。
    • 可以通过dtype参数在创建时指定数据类型。
  • 广播和矢量化运算:
    • 支持广播机制,允许对不同形状的数组进行算术运算。
    • 提供矢量化操作,避免使用Python循环,极大地提高了性能。
  • 丰富的函数库:
    • 包含大量用于线性代数、傅里叶变换、统计运算等的函数。
    • 提供了高级的数组操作,如切片、重塑、拼接等。

总结

  • 适用场景:
    • array模块:适用于需要高效存储和操作基本类型数据的简单场景。
    • NumPyndarray:适用于科学计算、数值分析和处理大规模数值数据的复杂场景,提供了丰富的数学函数和高效的操作。
  • 功能性和性能:
    • array模块:功能相对简单,适合基本的数据存储和简单操作。
    • NumPyndarray:功能强大,性能非常高,特别是对于大规模数值计算。

在大多数科学计算和数据分析场景中,NumPy的ndarray是首选工具,因为它提供了更高级的功能和更高的性能。对于简单的数据存储和操作,array模块也是一个不错的选择。

Python array的元素类型

在Python的array模块中,数组中的所有元素必须是相同的数据类型。这是通过在创建数组时指定一个类型码来实现的。类型码决定了数组中元素的数据类型和存储方式。以下是array模块中常用的类型码及其对应的C语言数据类型和Python等效类型:

import array
array.typecodes
'bBuhHiIlLqQfd'

常用类型码

  • ‘b’:有符号字符(signed char),对应于Python中的int。
  • ‘B’:无符号字符(unsigned char),对应于Python中的int。
  • ‘u’:Unicode字符,表示为Python的str类型(注意:长度固定为2字节或4字节,具体取决于系统)。
  • ‘h’:有符号短整型(signed short),对应于Python中的int。
  • ‘H’:无符号短整型(unsigned short),对应于Python中的int。
  • ‘i’:有符号整型(signed int),对应于Python中的int。
  • ‘I’:无符号整型(unsigned int),对应于Python中的int。
  • ‘l’:有符号长整型(signed long),对应于Python中的int。
  • ‘L’:无符号长整型(unsigned long),对应于Python中的int。
  • ‘q’:有符号长长整型(signed long long),对应于Python中的int。
  • ‘Q’:无符号长长整型(unsigned long long),对应于Python中的int。
  • ‘f’:浮点型(float),对应于Python中的float。
  • ‘d’:双精度浮点型(double),对应于Python中的float。

您可以检查具体数组的.itemsize属性,以准确了解其元素之一将在内存中占用多少字节。同样,您可以读取数组的.typecode属性以显示用于创建该数组的字母。这两个属性都是只读的。

>>> from array import array
>>> array("i").itemsize
4
>>> array("i").typecode
'i'

Python array的基本使用

Python的array模块提供了一种用于存储相同类型元素的数组类型。虽然不如NumPy的ndarray功能强大,但对于简单的数据存储和操作,它是一个轻量级的选择。以下是array模块的基本使用方法:

导入模块

首先,你需要导入array模块:

import array

创建数组

使用array.array()函数创建数组。这个函数需要两个参数:类型码和初始化列表。

# 创建一个整数数组
int_array = array.array('i', [1, 2, 3, 4])

# 创建一个浮点数数组
float_array = array.array('f', [1.0, 2.0, 3.0])

访问元素

可以通过索引访问数组中的元素,类似于Python列表:

print(int_array[0])  # 输出: 1

修改元素

可以通过索引修改数组中的元素:

int_array[0] = 10
print(int_array)  # 输出: array('i', [10, 2, 3, 4])

添加元素

可以使用append()方法在数组末尾添加元素:

int_array.append(5)
print(int_array)  # 输出: array('i', [10, 2, 3, 4, 5])

插入元素

可以使用insert()方法在指定位置插入元素:

int_array.insert(1, 20)
print(int_array)  # 输出: array('i', [10, 20, 2, 3, 4, 5])

删除元素

可以使用remove()方法删除第一个匹配的元素:

int_array.remove(20)
print(int_array)  # 输出: array('i', [10, 2, 3, 4, 5])
可以使用pop()方法删除指定位置的元素:
int_array.pop(1)
print(int_array)  # 输出: array('i', [10, 3, 4, 5])

数组长度

可以使用len()函数获取数组的长度:

length = len(int_array)
print(length)  # 输出: 4

数组遍历

可以使用循环遍历数组中的元素:

for element in int_array:
    print(element)

Python array与其他类型的转换

在Python中,array模块提供了基础的数组数据结构,用于存储相同类型的元素。在某些情况下,你可能需要在array数组和其他数据类型(如列表、字符串、字节等)之间进行转换。以下是一些常见的转换方法:

数组转换为列表

可以使用tolist()方法将array数组转换为Python列表:

import array

# 创建一个整数数组
int_array = array.array('i', [1, 2, 3, 4])

# 转换为列表
list_version = int_array.tolist()
print(list_version)  # 输出: [1, 2, 3, 4]

列表转换为数组

可以在创建数组时传入列表来实现从列表到数组的转换:

import array

# 创建一个整数列表
int_list = [1, 2, 3, 4]

# 转换为数组
int_array = array.array('i', int_list)
print(int_array)  # 输出: array('i', [1, 2, 3, 4])

数组转换为字符串

对于字符数组,可以使用tounicode()(对于’u’类型码)将数组转换为字符串:

import array

# 创建一个Unicode字符数组
char_array = array.array('u', 'hello')

# 转换为字符串
str_version = char_array.tounicode()
print(str_version)  # 输出: 'hello'

字符串转换为数组

可以直接将字符串传入数组构造函数(对于’u’类型码):

import array

# 创建一个Unicode字符数组
char_array = array.array('u', 'hello')
print(char_array)  # 输出: array('u', 'hello')

数组转换为字节

可以使用tobytes()方法将数组转换为字节对象:

import array

# 创建一个整数数组
int_array = array.array('i', [1, 2, 3, 4])

# 转换为字节
bytes_version = int_array.tobytes()
print(bytes_version)  # 输出: b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'

字节转换为数组

可以使用frombytes()方法将字节对象转换为数组:

import array

# 创建一个空的整数数组
int_array = array.array('i')

# 从字节对象创建数组
int_array.frombytes(b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00')
print(int_array)  # 输出: array('i', [1, 2, 3, 4])

Python array 的文件读写

Python的array模块提供了.tofile()和.fromfile()方法,用于将数组的数据写入文件和从文件中读取数据。这对于需要将数组数据持久化到磁盘或者从磁盘加载数组数据的场景非常有用。下面是这两个方法的详细介绍和使用示例。

.tofile()

.tofile()方法将数组的内容以二进制格式写入文件。这种方法对于需要快速存储和读取大量数据的场景非常高效。

import array

# 创建一个整数数组
int_array = array.array('i', [1, 2, 3, 4, 5])

# 将数组写入文件
with open('array_data.bin', 'wb') as file:
    int_array.tofile(file)

在这个例子中,整数数组int_array被写入到名为array_data.bin的文件中。请注意,这里文件是以二进制写模式’wb’打开的。

.fromfile()

.fromfile()方法从文件中读取数据并填充数组。读取的数据必须与数组的类型码相匹配,并且文件中的数据格式必须与.tofile()写入的数据格式相同。

import array

# 创建一个空的整数数组
int_array = array.array('i')

# 从文件中读取数据到数组
with open('array_data.bin', 'rb') as file:
    int_array.fromfile(file, 5)  # 第二个参数是要读取的元素个数

print(int_array)  # 输出: array('i', [1, 2, 3, 4, 5])

在这个例子中,我们从array_data.bin文件中读取5个整数,并将它们存储到int_array中。文件是以二进制读模式’rb’打开的。

注意事项

  • 数据格式:.tofile()和.fromfile()方法以二进制格式处理数据,因此在不同平台之间传输文件时要注意字节序(endianness)问题。
  • 文件模式:确保在使用.tofile()时以’wb’模式打开文件,而在使用.fromfile()时以’rb’模式打开文件。
  • 元素个数:在使用.fromfile()时,必须指定要读取的元素个数。如果文件中的数据少于指定的个数,可能会导致读取错误。
  • 文件内容:fromfile()方法假设文件的内容格式与.tofile()方法写入的格式一致。因此,确保在读取时文件未被其他方式修改。

通过使用.tofile()和.fromfile()方法,你可以高效地将数组数据保存到文件中,并从文件中恢复数据。这在需要处理大规模数据或需要将数据持久化的应用中非常有用。

参考链接:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注