说起编程里的“数组”,很多人脑子里立刻蹦出来的是C、C++或者Java里那种规规矩矩、大小固定、元素类型还得一模一样的数据结构。它们就像一排排整齐划一的小盒子,每个盒子里放着同样规格的东西,找起来飞快。但当你一头扎进 Python 的世界,想问“python怎么定义数组”,嘿,你可能会发现,Python这小家伙,骨子里就没有那种原生的、固定大小数组类型。它更像是一个百变金刚,用几种不同的方式来满足你对“数组”的需求,每种都有自己的脾气和擅长的事儿。

别急着挠头,这恰恰是Python的魅力所在——它给了你灵活性,也提供了高性能的选择,就看你怎么用。

第一站:Python里的“万金油”——列表 (list)

如果你只是想随便存一堆东西,顺序有点讲究,数量不确定,而且里头的东西可能啥类型都有,那Python内置的列表list)绝对是你的首选。说白了,它就是Python里最常用、最顺手的序列类型,虽然不是传统意义上的数组,但绝大多数时候,我们用它来扮演数组的角色。

想定义一个列表?简单到爆!就像列购物清单一样,用方括号 [] 把你要装进去的东西一字儿排开,用逗号隔开,齐活儿!

“`python

定义一个装着各种东西的列表

my_shopping_list = [‘apple’, 1, True, 3.14, ‘banana’]

或者一个空列表,等会儿再往里塞东西

empty_list = []
“`

看到了吗?my_shopping_list 里啥都有,字符串、整数、布尔值、浮点数,列表不挑食!这一点跟那些规矩的传统数组完全不一样,后者可是有严格的类型要求

列表的操作简直是“随心所欲”。想往里加东西?用 .append() 加到末尾,或者 .insert(index, element) 塞到指定位置。想拿掉点啥? .remove(value) 按值删除, .pop(index) 按索引删除(还能把删掉的那个值给你返回),或者更直接点,用 del list[index] 或者 del list[start:end] 直接根据索引或者切片“砍”掉。

python
my_list = [10, 20, 30]
my_list.append(40) # [10, 20, 30, 40]
my_list.insert(1, 15) # [10, 15, 20, 30, 40]
my_list.remove(20) # [10, 15, 30, 40]
popped_value = my_list.pop(2) # popped_value is 30, my_list is [10, 15, 40]
del my_list[0] # my_list is [15, 40]

访问列表里的元素也跟数组挺像,用索引就行,记住:Python的索引也是从0开始的!

python
first_item = my_list[0] # 拿到第一个
last_item = my_list[-1] # 负数索引,从后往前数,-1就是最后一个

切片slicing)更是Python列表的一大杀器,想取列表中某一段?简直不要太方便!

“`python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]

拿到前三个

first_three = numbers[:3] # [1, 2, 3]

拿到索引2到索引5(不包括5)

slice_of_life = numbers[2:5] # [3, 4, 5]

从索引4开始到最后

rest_of_it = numbers[4:] # [5, 6, 7, 8, 9]

每隔一个取一个

every_other = numbers[::2] # [1, 3, 5, 7, 9]
“`

所以你看,列表的灵活性爆炸!大小可变,内容异构,操作方便。对于日常的数据收集、临时存储、或者那些你不太确定数据量、数据类型会怎么变动的场景,列表是妥妥的“万金油”。

但是,列表有没有缺点? 当然有!正因为它的灵活性,它在内存里的存储可能不是连续的,而且需要维护元素的类型信息等等。这导致如果你要处理海量同质数据,并且进行大量的数值计算,比如成千上万个数字相加、相乘、矩阵运算啥的,列表的处理速度就会显得非常慢。这时候,你就需要更“硬核”的家伙了。

第二站:Python里的“定海神针”——元组 (tuple)

有时候,你需要一组数据,它们是相关的,你想把它们捆在一起,但又不希望它们在使用过程中被不小心修改。这时候,元组tuple)就派上用场了。你可以把它想象成一个“不可变”的列表。一旦定义了,里面的元素顺序和值就不能变了。

定义一个元组,用小括号 () 或者仅仅用逗号隔开元素就行(单个元素记得加逗号):

“`python

定义一个表示坐标的元组

coordinates = (10, 20)

或者一个表示颜色的RGB值

rgb_color = 255, 0, 100 # 括号可以省略

包含一个元素的元组,这个逗号很重要!

single_tuple = (5,)

空元组

empty_tuple = ()
“`

跟列表一样,元组里的元素也可以是不同类型的。访问元素和切片也跟列表一模一样,用索引 [] 就行。

python
x = coordinates[0] # 拿到第一个元素 10
subset = rgb_color[1:] # 拿到 [0, 100]

但记住,元组是不可变的!这意味着你不能对它进行增删改的操作,比如 coordinates[0] = 15 或者 coordinates.append(30) 都会报错!

“`python

尝试修改元组元素会报错!

coordinates[0] = 15 # TypeError: ‘tuple’ object does not support item assignment

“`

那为啥还需要元组呢?它的不可变性本身就是一种优势:
1. 安全性: 作为函数返回值或者在多线程环境下传递数据时,不用担心原始数据被意外修改。
2. 作为字典的键: 列表不能作为字典的键,因为它可变,而元组可以,因为它不可变,满足了字典键需要可哈希(hashable)的要求。
3. 函数返回多个值: Python函数默认返回一个元组,非常方便。比如 divmod(10, 3) 返回 (3, 1)

所以,元组不是用来替代列表做通用“数组”的,它是为了那些需要固定不变序列数据的场景而生的。

第三站:Python里的“高性能怪兽”——NumPy数组 (ndarray)

前面说了,列表在处理大量数值计算时会跪。那怎么办?难道要退回C++?当然不!Python有自己的科学计算利器——NumPy库。它提供了真正意义上的多维数组对象,叫做 ndarray(n-dimensional array),这才是你在Python里进行高效数值计算数据分析机器学习等等任务时,定义“数组”的首选,甚至是必选

NumPy数组跟列表最大的区别是:它要求里面的元素必须是同一种类型的(比如都是整数,或者都是浮点数),并且在创建时就确定了形状(维度和大小)。这听起来有点像传统的数组了,没错,NumPy就是为了弥补Python列表在数值计算上的不足而设计的。它的底层很多代码是用C或Fortran写的,速度飞快!

要使用NumPy,得先安装它(pip install numpy)和导入它(通常约定俗成导入为 np):

“`python
import numpy as np

定义一个NumPy数组

通常从一个Python列表或者元组创建

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

定义一个二维数组(矩阵)

my_matrix = np.array([[1, 2, 3], [4, 5, 6]])
“`

除了从Python序列创建,NumPy还提供了很多方便的函数来快速生成特定类型的数组:

“`python

创建一个全零的数组

zeros_array = np.zeros(5) # [0., 0., 0., 0., 0.] (默认是浮点数)

创建一个全一的3×3矩阵

ones_matrix = np.ones((3, 3))

创建一个等差数列

arange_array = np.arange(0, 10, 2) # 从0到10,步长为2 -> [0, 2, 4, 6, 8]

创建一个指定数量的等间隔数组

linspace_array = np.linspace(0, 1, 5) # 在0到1之间生成5个等间隔的数 -> [0., 0.25, 0.5, 0.75, 1.]

创建一个指定形状的随机数数组

random_array = np.random.rand(2, 3) # 生成一个2×3的随机数矩阵
“`

NumPy数组的操作语法跟列表类似,也支持索引切片,而且功能更强大,支持更多高级的索引方式(比如布尔索引、花式索引)。

“`python

访问元素和切片跟列表类似

element = my_np_array[2] # 拿到第三个元素 3
row = my_matrix[0] # 拿到第一行 [1, 2, 3]
sub_matrix = my_matrix[:, 1:] # 拿到所有行的第二列及以后
“`

NumPy最牛的地方在于它的向量化操作。你可以直接对整个数组或者数组之间进行数学运算,NumPy会在底层以非常高效的方式完成,完全不需要你自己写for循环!这正是它比列表快上好几个数量级的秘诀。

“`python
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

数组相加,对应元素相加

c = a + b # [5, 7, 9]

数组乘以一个标量

d = a * 2 # [2, 4, 6]

矩阵乘法(注意是 @ 运算符)

matrix_a = np.array([[1, 2], [3, 4]])
matrix_b = np.array([[5, 6], [7, 8]])
product = matrix_a @ matrix_b # 执行矩阵乘法
“`

这种直接对数组进行操作的方式,不仅写起来简洁,更重要的是运行速度爆炸快!当你处理的数据量是百万、千万甚至上亿级别的时候,列表可能算到天荒地老,NumPy可能几秒钟就搞定了。

所以,如果你在做数据处理图像处理信号处理机器学习模型训练等等任何涉及到大量数值计算的任务,请毫不犹豫地选择NumPy数组!它才是Python在这些领域的基石

总结一下(非严格的总结,只是拉个家常):

问“python怎么定义数组”,其实背后是问“在Python里怎么存一堆有序的数据”。Python没有那种死板的传统数组,它给了你更灵活和更专业的选择:

  • 列表 (list): 你的日常万金油。灵活、方便、啥都能装、大小随意变。适合数据类型多样的、不确定大小的、不需要高性能数值计算的场景。就像个随手可得的袋子,往里塞啥都行。
  • 元组 (tuple): 需要一组固定不变的数据时用它。操作跟列表类似,但一旦创建不能修改。适合表示坐标、RGB值、或者函数返回多个值等等需要确保数据不被篡改的场景。像个密封的盒子,装好就不能再动了。
  • NumPy数组 (ndarray): 你的高性能计算利器。元素同质、大小固定(相对),支持向量化操作,速度飞快。是进行科学计算数据分析机器学习等任务时处理大量数值数据标准答案。这是个经过精心设计的、超能装、处理效率奇高的专业存储柜。

刚开始学Python,列表绝对够你玩转大部分场景。但当你的数据量开始变大,计算需求开始提高时,别忘了去拥抱NumPy,它会让你见识到Python在科学计算领域的真正实力。

所以下次有人再问你“python怎么定义数组”,你就可以挺起胸膛告诉他:“Python没有原生的传统数组,但它有列表、元组和NumPy数组,每种都有自己的绝活儿,得看你具体想干啥!” 这回答是不是比简单说“用列表啊”要更有深度,更贴近Python这门语言的“性格”?

选择哪个,取决于你的数据特性使用场景。理解了它们的区别和各自的优势,你才能在Python的世界里更游刃有余地处理数据,发挥出Python的最大潜力。别走弯路,根据实际需求选对工具,事半功倍!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。