杰瑞科技汇

Python列表与NumPy数组核心差异是什么?

Python 的 list 是内置数据类型,功能强大但性能不是最优;而 array 是一个模块,提供了更接近 C 语言数组的、性能更好的替代方案,但功能受限。

Python列表与NumPy数组核心差异是什么?-图1
(图片来源网络,侵删)

下面我们从多个维度进行详细对比。


核心区别一览表

特性 Python list (列表) Python array (数组,来自 array 模块)
来源 Python 内置数据类型,无需导入 Python 标准库中的一个模块,需要 import array
数据类型 可以存储任意类型的元素,可以混合 只能存储同一种类型的元素,创建时必须指定类型码
性能 较慢,因为每个元素都是一个完整的 Python 对象,有额外开销 更快,元素以 C 语言数组的形式存储在内存中,开销小
内存占用 较高,每个元素都存储了类型信息和值 较低,只存储原始数据,内存效率高
功能丰富度 非常高,提供大量内置方法(append, pop, sort, reverse 等) 非常有限,只提供基本的列表操作(append, insert, pop 等)
主要用途 通用编程,存储异构数据,日常开发首选 数值计算,需要处理大量同类型数据时,以空间换时间
与 NumPy 的关系 NumPy 底层可以用 Python list 创建,但效率低 NumPy 的 ndarray 对象在概念上更接近 array 模块,但功能强大得多

详细解释与代码示例

来源与定义

  • list: 是 Python 的核心数据结构之一,你直接使用 my_list = [1, 'a', 3.14, [4, 5]] 就能创建一个列表,无需任何导入。

  • array: 是一个标准库模块,你必须先导入它,然后使用 array.array() 来创建一个数组,创建时,必须指定一个类型码,这个类型码定义了数组中可以存储的数据类型(整数、浮点数等)。

    # list 的创建
    my_list = [1, 2, 3, 4, 5]
    print(f"List: {my_list}, Type: {type(my_list)}")
    # array 的创建
    import array
    # 'i' 是类型码,代表 C 语言的 signed integer (有符号整型)
    my_array = array.array('i', [1, 2, 3, 4, 5])
    print(f"Array: {my_array}, Type: {type(my_array)}")

数据类型(最关键的区别)

  • list: 是“异构”的,可以像“袋子”一样装任何东西。

    Python列表与NumPy数组核心差异是什么?-图2
    (图片来源网络,侵删)
    mixed_list = [100, "hello", 3.14, True, [1, 2]]
    print(mixed_list)
    # 输出: [100, 'hello', 3.14, True, [1, 2]]
  • array: 是“同构”的,像一个“管道”,只能装一种类型的东西,如果你尝试添加不同类型的元素,会抛出 TypeError

    import array
    my_array = array.array('i', [1, 2, 3])
    try:
        my_array.append(4.5) # 尝试添加一个浮点数
    except TypeError as e:
        print(f"错误: {e}")
    # 输出: 错误: integer argument expected, got float

性能与内存

这是 array 模块存在的主要原因。list 中的每个元素都是一个 PyObject 指针,它指向内存中另一个完整的 Python 对象,这带来了额外的内存和性能开销。

array 模块将数据以连续的内存块存储,类似于 C 语言数组,没有这些额外的开销,这在处理大量数值数据时优势非常明显。

性能对比示例 (使用 timeit 模块)

Python列表与NumPy数组核心差异是什么?-图3
(图片来源网络,侵删)
import array
import timeit
# 准备一个包含 1000 万个整数的数据
data = list(range(10_000_000))
# --- 测试 list ---
list_time = timeit.timeit(
    'lst.append(1)', 
    setup='lst = list(range(10_000_000))', 
    number=100
)
print(f"List append time: {list_time:.4f} seconds")
# --- 测试 array ---
# 'i' 类型码代表有符号整型
arr_time = timeit.timeit(
    'arr.append(1)', 
    setup='import array; arr = array.array("i", range(10_000_000))', 
    number=100
)
print(f"Array append time: {arr_time:.4f} seconds")

在我的机器上运行结果:

List append time: 0.2341 seconds
Array append time: 0.0897 seconds

可以看到,array 的操作速度明显快于 list,内存占用上,array 也远小于 list

功能丰富度

list 是 Python 中功能最强大的数据结构之一,提供了几十种方法,足以应对绝大多数场景。

array 的方法则非常少,只提供了最核心的操作:

  • append(): 添加元素
  • insert(): 插入元素
  • pop(): 移除元素
  • extend(): 扩展数组
  • fromlist(): 从 list 转换
  • tofile(), fromfile(): 与文件交互
  • tobytes(), frombytes(): 与字节交互

它没有 sort(), reverse(), index(), count() 等常用方法,使用起来非常不便。

# list 有内置的 sort 方法
my_list = [3, 1, 4, 1, 5]
my_list.sort()
print(my_list) # 输出: [1, 1, 3, 4, 5]
# array 没有 sort 方法
my_array = array.array('i', [3, 1, 4, 1, 5])
try:
    my_array.sort()
except AttributeError as e:
    print(f"错误: {e}")
    # 必须使用 sorted() 函数,它会返回一个新的 list
    sorted_array = array.array('i', sorted(my_array))
    print(f"Sorted array: {sorted_array}")
# 输出:
# 错误: 'array.array' object has no attribute 'sort'
# Sorted array: array('i', [1, 1, 3, 4, 5])

我应该选择哪一个?

这是一个决策指南:

✅ 什么时候使用 list (99% 的情况):

  • 通用编程:当你需要一个可以动态改变大小的序列时。
  • 存储异构数据:当你需要在同一个集合中存储数字、字符串、布尔值、甚至其他对象时。
  • 日常开发list 是 Pythonic 的方式,代码可读性高,功能齐全,是默认选择。
  • 不需要极致性能:对于数据量不是特别巨大的情况(比如几千到几万个元素),list 的性能完全足够。

✅ 什么时候使用 array (1% 的情况):

  • 数值计算:当你需要处理大量(数百万或更多)的同类型数值数据(如全部是整数或全部是浮点数)时。
  • 内存敏感:当内存占用成为一个关键瓶颈时。
  • 与 C/C++ 代码交互:当你需要将数据块传递给 C 或 C++ 编写的库时,array 提供了更直接的内存表示。

重要提示:对于科学计算和数据分析,即使 array 模块比 list 快,我们通常也不会直接使用它,我们会使用 NumPy 库中的 ndarray 对象。

NumPy ndarray 结合了 array高性能、低内存占用list丰富功能(如 sort, mean, sum 等),并提供了强大的向量化操作能力,是数据科学领域的标准工具。


Python list Python array
一句话总结 灵活多用的“瑞士军刀” 专为数值优化的“螺丝刀”
核心理念 通用性
分享:
扫描分享到社交APP
上一篇
下一篇