Python 数组指南

Python 数组指南

介绍

想象一下,您的手机上有一个您最喜欢的歌曲的播放列表。 该播放列表是每首歌曲按特定顺序放置的列表。 您可以播放第一首歌曲,跳到第二首,跳到第五首,依此类推。 这个播放列表很像计算机编程中的数组。

数组是最基本、最广泛使用的数据结构之一。

本质上,数组是一种以特定顺序存储多个项目(如数字、字符甚至其他数组)的结构化方式,如果知道其位置(索引),您可以快速访问、修改或删除任何项目。

在本指南中,我们将为您提供数组数据结构的全面概述。 首先,我们来看看什么是数组以及它们的主要特征是什么。 然后我们将进入 Python 世界,探索如何在现实场景中实现、操作和应用数组。

了解数组数据结构

数组是计算机科学和编程中使用的最古老和最基本的数据结构之一。 它们的简单性加上某些操作的效率,使它们成为任何深入研究数据管理和操作领域的人的主要主题。

数组是项目的集合,通常是 同类型,存储在 连续的内存位置.

这种连续存储允许数组在给定索引的情况下提供对任何元素的恒定时间访问。 数组中的每一项称为 element,数组中元素的位置由其定义 指数,通常 从零开始.

例如,考虑一个整数数组: [10, 20, 30, 40, 50]。 在这里,元素 20 有一个索引 1:

python 数组索引

有多个 优点 使用数组来存储我们的数据。 例如,由于其内存布局,数组允许 O(1) 通过索引访问元素时的(恒定)时间复杂度。 当我们需要随机访问元素时,这特别有用。 此外,数组存储在 连续的内存位置,这可以在某些操作中带来更好的缓存局部性和整体性能改进。 使用数组的另一个显着优点是,由于数组一旦声明就有固定的大小,因此更容易管理内存并避免意外溢出或内存不足错误。

备注:数组在以下情况下特别有用: 集合的大小是预先知道的并且保持不变,或者随机访问比插入和删除更频繁的情况。

另一方面,数组有自己的一组 限制。 传统阵列的主要限制之一是它们 固定尺寸。 数组一旦创建,其大小就无法更改。 这可能会导致内存浪费(如果数组太大)或需要调整大小(如果数组太小)等问题。 除此之外,在数组中间插入或删除元素需要移动元素,导致 O(N) 这些操作的时间复杂度。

总而言之,让我们使用本指南开头的歌曲播放列表示例来说明数组的主要特征。 数组是一种数据结构:

  • 已编入索引: 就像播放列表中的每首歌曲都有一个编号(1、2、3……)一样,数组中的每个元素都有一个索引。 但是,在大多数编程语言中,索引从 0 开始。因此,第一项位于索引 0,第二项位于索引 1,依此类推。

  • 有固定尺寸:当您为 10 首歌曲创建播放列表时,如果不先删除一首歌曲,则无法添加第 11 首歌曲。 同样,数组也有固定的大小。 一旦创建了一定大小的数组,就无法添加超过其容量的项目。

  • 是同质的:播放列表中的所有歌曲都是音乐曲目。 同样,数组中的所有元素都具有相同的类型。 如果您有一个整数数组,则无法突然在其中存储文本字符串。

  • 可以直接访问:如果您想听播放列表中的第 7 首歌曲,可以直接跳到该歌曲。 类似地,对于数组,如果知道其索引,则可以立即访问任何元素。

  • 连续内存: 这有点技术性。 当一个数组在计算机内存中创建时,它会占用一块连续的内存块。 可以把它想象成学校里一排相邻的储物柜。 每个储物柜都是相邻的,之间没有间隙。

Python 和数组

Python 以其灵活性和易用性而闻名,提供了多种使用数组的方法。 虽然 Python 不像其他一些语言那样具有原生数组数据结构,但它提供了功能类似的强大替代方案,甚至提供扩展功能。

乍一看, Python 的列表 可能看起来与数组同义,但有一些细微的差别和细微差别需要考虑:

清单 排列
内置 Python 数据结构 不是 Python 原生的——它们来自“array”模块
动态尺寸 固定(预定义)大小
可以容纳不同数据类型的项目 持有相同类型的物品
提供一系列内置的操作方法 需要导入外部模块
访问操作的时间复杂度为 O(1) 访问操作的时间复杂度为 O(1)
消耗更多内存 内存效率更高

看到这张表,人们自然会问—— “什么时候用哪个?”。 好吧,如果您需要一个可以动态增长或收缩并可以容纳混合数据类型的集合,Python 的列表就是您的最佳选择。 但是,对于需要具有相同类型元素的内存效率更高的集合的场景,您可以考虑使用 Python array 模块或外部库(如 NumPy)。

排列 Python 中的模块

当大多数开发人员想到 Python 中的数组时,他们通常会默认想到列表。 然而,Python 通过其内置提供了更专门的数组结构 array 模块。 该模块在 Python 中提供了基本 C 风格数据类型的节省空间的存储。

虽然 Python 列表的用途非常广泛,并且可以存储任何类型的对象,但它们有时可能有点过头了,特别是当您只需要存储基本数据类型的集合(例如整数或浮点数)时。 这 array 模块提供了一种创建数组的方法,该数组比特定数据类型的列表具有更高的内存效率。

创建一个数组

要使用 array 模块,首先需要导入它:

from array import array

导入后,您可以使用以下命令创建数组 array() 构造函数:

arr = array('i', [1, 2, 3, 4, 5])
print(arr)

在这里, 'i' 参数表示数组将存储带符号的 整数。 还有其他几种可用的类型代码,例如 'f' 对于浮动和 'd' 双打。

访问和修改元素

您可以像使用列表一样访问和修改数组中的元素:

print(arr[2]) 

现在,让我们修改该元素,将其值更改为 6:

arr[2] = 6
print(arr) 

数组方法

array 模块提供了几种操作数组的方法:

  • append() – 在数组末尾添加一个元素:

    arr.append(7)
    print(arr) 
  • extend() – 将可迭代元素附加到末尾:

    arr.extend([8, 9])
    print(arr) 
  • pop() – 删除并返回给定位置的元素:

    arr.pop(2)
    print(arr) 
  • remove():删除第一次出现的指定值:

    arr.remove(2)
    print(arr) 
  • reverse():反转数组的顺序:

    arr.reverse()
    print(arr) 

请注意: 还有比我们在这里列出的更多的方法。 请参阅 官方 Python 文档 查看所有可用方法的列表 array 模块。

虽然 array 模块提供了一种更节省内存的方式来存储基本数据类型,记住它是很重要的 限制。 与列表不同,数组是 同质。 这意味着数组中的所有元素必须属于同一类型。 另外,您只能存储 基本 C 风格数据类型 在数组中。 如果需要存储自定义对象或其他 Python 类型,则需要使用列表或其他数据结构。

NumPy 数组

NumPy 是 Numerical Python 的缩写,是 Python 中数值计算的基础包。 其主要特点之一是其强大的 N维数组对象,它提供了对数组的快速操作,包括数学、逻辑、形状操作等。

NumPy 数组比 Python 内置的更通用 array 模块,是数据科学和机器学习项目的主要内容。

为什么使用 NumPy 数组?

首先想到的是 性能。 NumPy 数组是用 C 语言实现的,由于优化的算法和连续内存存储的优点,可以实现高效的内存存储和更快的操作。

虽然 Python 的内置列表和数组是一维的,但 NumPy 数组可以是一维的 多维的,使它们非常适合表示矩阵或张量。

查看我们的 Git 学习实践指南,其中包含最佳实践、行业认可的标准以及随附的备忘单。 停止谷歌搜索 Git 命令,实际上 学习 它!

最后,NumPy 提供了一个 大量的功能 对这些数组进行操作,从基本算术到高级数学运算、整形、分割等。

请注意: 当您提前知道数据的大小时,为数组预分配内存(尤其是在 NumPy 中)可以提高性能。

创建 NumPy 数组

要使用 NumPy,您首先需要安装它(pip install numpy)然后导入它:

import numpy as np

导入后,您可以使用以下命令创建 NumPy 数组 array() 功能:

arr = np.array([1, 2, 3, 4, 5])
print(arr) 

您还可以创建多维数组:

matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(matrix)

这将给我们:

[[1 2 3] [4 5 6] [7 8 9]]

除了这些创建数组的基本方法之外,NumPy 还为我们提供了其他创建数组的巧妙方法。 其中之一是 arange() 方法。 它创建具有定期递增值的数组:

arr = np.arange(10)
print(arr) 

另一个是 linspace() 方法,该方法创建具有指定数量元素的数组,这些元素在指定的开始值和结束值之间等距:

even_space = np.linspace(0, 1, 5)
print(even_space) 

访问和修改元素

访问和修改 NumPy 数组中的元素非常直观:

print(arr[2]) arr[2] = 6
print(arr) 

对多维数组做几乎相同的事情:

print(matrix[1, 2]) matrix[1, 2] = 10
print(matrix)

会改变第二行元素的值(索引 1)和第三列(索引 2):

[[1 2 3] [4 5 20] [7 8 9]]

改变数组的形状

NumPy 提供了许多函数和方法来操作和操作数组。 例如,您可以使用 reshape() 方法 改变数组的形状。 假设我们有一个简单的数组:

import numpy as np arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
print("Original Array:")
print(arr) 

我们想将其重塑为 3×4 矩阵。 您需要做的就是使用 reshape() 具有所需尺寸作为参数传递的方法:


reshaped_arr = arr.reshape(3, 4)
print("Reshaped Array (3x4):")
print(reshaped_arr)

这将导致:

Reshaped Array (3x4):
[[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12]]

矩阵乘法

numpy.dot() 方法用于 矩阵乘法。 它返回两个数组的点积。 对于一维数组,它是 内部产品 的数组。 对于二维数组,它相当于 矩阵乘法,对于 ND 来说,它是 和积 在第一个数组的最后一个轴和第二个数组的倒数第二个轴上。

让我们看看它是如何工作的。 首先,我们计算两个一维数组的点积(向量的内积):

import numpy as np vec1 = np.array([1, 2, 3])
vec2 = np.array([4, 5, 6])
dot_product_1d = np.dot(vec1, vec2) print("Dot product of two 1-D arrays:")
print(dot_product_1d) 

这将导致:

Dot product of two 1-D arrays:
32

32 事实上,是两个数组的内积 – (14 + 25+3*6)。 接下来,我们可以执行两个二维数组的矩阵乘法:


mat1 = np.array([[1, 2], [3, 4]])
mat2 = np.array([[2, 0], [1, 3]])
matrix_product = np.dot(mat1, mat2) print("Matrix multiplication of two 2-D arrays:")
print(matrix_product) 

这会给我们:

Matrix multiplication of two 2-D arrays:
[[ 4 6] [10 12]]

NumPy 数组是 Python 内置列表和 array 模块,特别是用于科学和数学计算。 它们的效率与 NumPy 库提供的丰富功能相结合,使它们成为任何想要在 Python 中进行数值运算的人不可或缺的工具。

结论

数组是计算机科学和编程的基石,已经在各种应用和领域中一次又一次证明了它们的价值。 在 Python 中,这种基本数据结构通过其各种形式(例如列表、 array 模块和强大的 NumPy 数组为开发人员提供了效率、多功能性和简单性的结合。

在本指南中,我们从数组的基本概念到它们在 Python 中的实际应用。 我们已经了解了数组如何凭借其内存连续的特性提供快速的访问时间,以及 Python 的动态列表如何带来额外的灵活性。 我们还深入研究了 NumPy 的专业领域,其中数组转变为强大的数值计算工具。

时间戳记:

更多来自 堆栈滥用