其实原生的Python是没有数组的(参考Java数组),只有元组(tuple)和列表(list),列表和java的List很像,可以随时增删元素,而元组相当于将列表只读化,不能增删内容。而和Java相对应的数组的概念,一般使用NumPy包的ndarray对象来进行操作。
接下来,分别介绍列表,元祖,ndarray数组的相关操作。
1. 列表
1.1 列表的初始化
创建一个空的列表
list_0 = []
初始化一维列表
# 已知元素
list_1_1 = [0, 1]
>>> [0, 1]
# 已知大小1
list_1_2 = [0] * 2
>>> [0, 0]
# 已知大小 (初始值0)
list_1_3 = [0 for i in range(3)]
>>> [0, 0, 0]
# 已知大小 (初始序列值)
list_1_3 = [i for i in range(3)]
>>> [0, 1, 2]
# 已知大小 (初始序列值)
list_1_3 = [i + 1 for i in range(3)]
>>> [1, 2, 3]
初始化二维列表
# 已知元素
list_2_1 = [ [0,0], [0,1], [1,0], [1,1] ]
# 已知大小 (不推荐)
list_2_2 = [[0] * 2] * 3
>>> [ [0,0], [0,0], [0,0] ]
# 不推荐这么做的原因是:这里的三个[0, 0]指向的是相同的list对象,比如:
list_2_2[0][1] = 1
>>> [ [0,1], [0,1], [0,1] ]
# 期待的是 [ [0,1], [0,0], [0,0] ]
# 已知大小 (推荐)
list_2_3 = [[0 for i in range(2)] for i range(3)]
>>> [ [0,0], [0,0], [0,0] ]
list_2_3[0][1] = 1
>>> [ [0,1], [0,0], [0,0] ]
通过list(<元组>)函数, 将元组转换成列表
tup_1 = (1, 2, 3)
list_1= list(tup_1)
>>> [1, 2, 3]
1.2 列表的读取及遍历
通过下标来获取指定维度的数据 (下标从0开始)
list_2 = [ [1,2], [3,4] ]
print(list_2[1][0])
>>> 3
通过 : 来截取范围
语法 列表对象[<开始index> : <结束index> : <步长> ]
list_1 = [ 0, 1, 2, 3, 4, 5 ]
list_1[:]
>>> [ 0, 1, 2, 3, 4, 5 ]
list_1[1:]
>>> [ 1, 2, 3, 4, 5 ]
list_1[:3]
>>> [ 0, 1, 2 ]
list_1[1:5]
>>> [ 1, 2, 3, 4 ]
list_1[1:5:2]
>>> [ 1, 3 ]
list_1[-2:] # 从最后一位往前截取2个, 相当于list_1[6-2:]
>>> [4, 5]
list_1[:-2] # 从倒数第二位(不包含)截取到开始, 相当于list_1[:6-2]
>>> [0, 1, 2, 3]
list_1[-4:-2] # 先从最后一位往前截取4个,然后截取的结果中再排除后两个,相当于list_1[6-4:6-2]
>>> [2, 3]
通过 for <列表项> in <列表> 遍历列表
for item in list_1:
print(item )
>>> [ 0, 1, 2, 3, 4, 5 ]
通过 for <索引> in range(len(<列表>)) 利用索引遍历列表
for index in range(len(list_1)):
print(index, list_1[index ])
>>> 0,0
>>> 1,1
>>> ...
>>> 5,5
通过 for <索引>, <列表项> in enumerate(<列表>, <起始位置>) 遍历索引和列表
for index, item in enumerate(list_1):
print(index, item)
>>> 0,0
>>> 1,1
>>> ...
>>> 5,5
1.3 列表元素的增删
增加元素
# 在尾部添加元素
list_1 = [1, 2]
list_1.append(3)
>>> [1, 2, 3]
# 将另外一个列表扩充到当前列表
list_1 = [1, 2]
list_1_1 = [3, 4]
list_1.extend(list_1_1)
>>> [1, 2, 3, 4]
# 将另外一个元组扩充到当前列表
list_1 = [1, 2]
tup_1 = (3, 4)
list_1.extend(tup_1)
>>> [1, 2, 3, 4]
# 在指定位置上插入元素
list_1 = [1, 3]
list_1.insert(1, 2)
>>> [1, 2, 3]
删除元素
# 删除指定元素
list_1 = ['a', 'b', 'c']
list_1.remove('b')
>>> ['a', 'c']
# 删除最后一个元素,并返回这个元素
list_1 = ['a', 'b', 'c']
list_1.pop() # 这里返回 'c'
>>> ['a', 'b']
# 清除所有元素
list_1 = ['a', 'b', 'c']
list_1.clear()
>>> []
# 根据索引删除
list_1 = ['a', 'b', 'c']
del list_1[1]
>>> ['a', 'c']
# 删除所有列表
list_1 = ['a', 'b', 'c']
del list_1
1.4 列表操作
()可以反转列表中的元素
list_1 = ['a', 'b', 'c']
list_1.reverse()
>>> ['c', 'b', 'a']
1
2
3
sorted()和([func])可以对列表进行排序
list_1 = ['b', 'a', 'c']
# 不改变原表结构用sorted()
sorted(list_1)
>>> ['a', 'b', 'c']
print(list_1)
>>> ['b', 'a', 'c']
# 改变原有顺序用()
list_1.sort()
print(list_1)
>>> ['a', 'b', 'c']
# 指定排序Key
>>> [ [1, 2], [2, 3], [3, 1] ]
list_2.sort(key=lambda x:x[1])
>>> [ [3, 1], [1, 2], [2, 3] ]
2. 元组
元组与列表类似,不同之处在于元组的元素不能修改,列表使用方括号,元组使用小括号。
2.1 元组的初始化
创建一个空的列表
tup_0 = ()
1
初始化一维元组
# 已知元素
tup_1_1 = (0, 1)
>>> (0, 1)
# 已知元素(只有一个元素,需要加逗号)
tup_1_2 = (0,)
>>> (0,)
初始化二维元组
# 已知元素
tup_2_1 = ( (0,0), (0,1), (1,0), (1,1) )
通过tuple(<列表>)函数, 将列表转换成元组
list_1= [1, 2, 3]
tup_1 = tuple(list_1)
>>> (1, 2, 3)
任意无符号的对象,以逗号隔开,默认为元组
x, y = 1, 2
print(x)
print(y)
>>> 1
>>> 2
tup_1 = 1, 2
print(tup_1)
>>> (1, 2)
2.2 元组的读取及遍历 (与列表用法一样)
略
2.3 元组元素的增删
元组中的元素值是不允许修改的,但我们可以对元组进行连接组合, 生成一个新的元组。
tup_1_1 = (1, 2, 3)
tup_1_2 = (4, 5)
tup_1_3 = tup_1_1 + tup_1_2
>>> (1, 2, 3, 4, 5)
元组的元素也是不允许删除的,但是可以通过del语句删除整个元组
tup_1_1 = (1, 2, 3)
del tup_1_1
3. NumPy (ndarray)
NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。NumPy 最重要的一个特点是其 N 维数组对象 ndarray,它是一系列同类型数据的集合,以 0 下标为开始进行集合中元素的索引。
3.1 ndarray的初始化
使用empty()函数创建一个指定形状(shape)、数据类型(dtype)且未初始化的数组。(注:数组元素为随机值,因为它们未初始化)
import numpy as np
arr_1 = ((3, 2))
>>>array([[4.9e-324, 9.9e-324], [1.5e-323, 2.0e-323],[2.5e-323, 3.0e-323]])
# dtype指定类型
arr_2 = ((3, 2), dtype=str)
>>> array([['', ''], ['', ''], ['', '']])
使用zeros()函数创建指定大小的数组,数组元素以 0 来填充:
import numpy as np
arr_1 = ((3, 2))
>>> array([[0., 0.], [0., 0.], [0., 0.]])
# dtype指定类型
arr_2 = ((3, 2), dtype=int)
>>> array([[0, 0], [0, 0], [0, 0]])
使用ones()函数创建指定大小的数组,数组元素以 1 来填充:
import numpy as np
arr_1 = ((3, 2))
>>> array([[1., 1.], [1., 1.], [1., 1.]])
# dtype指定类型
arr_2 = ((3, 2), dtype=int)
>>> array([[1, 1], [1, 1], [1, 1]])
创建一个 ndarray 只需调用 NumPy 的 array 函数即可
(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)
参数说明
名称 描述
object 数组或嵌套的数列
dtype 数组元素的数据类型,可选
copy 对象是否需要复制,可选
order 创建数组的样式,"C"为行方向(C语言),"F"为列方向(Fortran语言),A为任意方向(默认)
subok 默认返回一个与基类类型一致的数组
ndmin 指定生成数组的最小维度
初始化一维数组
import numpy as np
# 根据列表来创建
arr_1_1 = ([1, 2, 3])
>>> array([1, 2, 3])
# 根据元组来创建
arr_1_2 = ((1, 2, 3))
>>> array([1, 2, 3])
初始化二维数组
import numpy as np
# 使用二维列表创建
list_2_1 = [ [1,2], [3,4] ]
arr_2_1 = (list_2_1)
>>> array([ [1,2], [3,4] ])
# 使用最小维度
list_1_1 = [1,2]
arr_2_2 = (list_1_1, ndmin=2)
>>> array([ [1,2] ])
asarray()函数类似于array(), 但没有subok和ndmin这两个参数:
import numpy as np
arr_1 = ([1, 2, 3])
>>> array([ 1, 2, 3 ])
利用arange()函数初始化1维数组和reshape()函数初始化多维数组:
import numpy as np
arr_1 = (6)
>>> array([0, 1, 2, 3, 4, 5])
arr_2 = arr_1.reshape(3, 2)
>>> array([ [0, 1], [2, 3], [4, 5] ])
arr_3 = arr_1.reshape(3, 2, 1)
>>> array([ [[0], [1]], [[2], [3]], [[4], [5]] ])
3.2 ndarray的读取及遍历 (与列表一样)
除了和列表一样的访问方法外,NumPy还提供了nditer迭代器对象
import numpy as np
arr_2 = ([ [1,2,3], [4,5,6]])
# 按C-Order (行优先)风格顺序遍历
for item in (arr_2 , order='C'):
print(item)
>>> 1, 2, 3, 4, 5, 6
# 按F-Order(列优先)风格顺序遍历
for item in (arr_2 , order='F'):
print(item)
>>> 1, 4, 2, 5, 3, 6
# order参数如果不指定的化,会按照创建数组时指定的顺序来
arr_3 = ([ [1,2,3], [4,5,6] ], order='F')
for item in (arr_3):
print(item)
>>> 1, 4, 2, 5, 3, 6
3.3 ndarray元素的增删
(arr, values, axis=None)函数在数组的末尾, 返回一个新的数组,相当于列表中的extend()函数
import numpy as np
# axis默认为None,返回一个一维数组
arr_1 = ([ [1,2,3], [4,5,6] ])
(arr_1, [7,8,9])
>>> [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 在0维度增加元素
arr_1 = ([ [1,2,3], [4,5,6] ])
(arr_1, [ [7,8,9] ], axis=0)
>>> [ [1,2,3], [4,5,6], [7,8,9] ]
# 在1维度增加元素
arr_1 = ([ [1,2,3], [4,5,6] ])
(arr_1, [ [6], [15] ], axis=1)
>>> [ [1,2,3,6], [4,5,6,15] ]
# 在2维度增加元素
arr_1 = ([ [[1],[2],[3]], [[4],[5],[6]] ])
(arr_1, [ [[11],[22],[33]], [[44],[55],[66]] ], axis=2)
>>> [ [[1,11], [2,22], [3,33]], [[4,44], [5,55], [6,66]] ]
(arr, indexObj, values, axis)函数在指定位置插入一个数组, 返回一个新的数组,相当于列表中的insert()函数
import numpy as np
# axis默认为None,返回一个一维数组
arr_1 = ([ [1,2,3], [4,5,6] ])
(arr_1, 1, [7,8,9])
>>> [1, 7, 8, 9, 2, 3, 4, 5, 6]
# 在0维度插入元素
arr_1 = ([ [1,2,3], [4,5,6] ])
(arr_1, 1, [ [7,8,9] ], axis=0)
>>> [ [1,2,3], [7,8,9], [4,5,6] ]
# 在1维度插入元素
arr_1 = ([ [1,2,3], [4,5,6] ])
(arr_1, (1,), [ [6], [15] ], axis=1)
>>> [ [1,6,2,3], [4,15,5,6] ]
# 在2维度插入元素
arr_1 = ([ [[1],[2],[3]], [[4],[5],[6]] ])
(arr_1, (0,), [ [[11],[22],[33]], [[44],[55],[66]] ], axis=2)
>>> [ [[11,1], [22,2], [33,3]], [[44,4], [55,5], [66,6]] ]
(arr, obj, axis)函数返回从输入数组中删除指定子数组的新数组
import numpy as np
# axis默认为None,在删除之前输入数组会被展开
arr_1 = ([ [1,2,3], [4,5,6] ])
(arr_1, 1) # 删除1位置上的元素
>>> [1, 3, 4, 5, 6]
# 在0维度删除元素
arr_1 = ([ [1,2,3], [4,5,6] ])
(arr_1, 1, axis=0)
>>> [ [1,2,3] ]
# 在1维度删除元素
arr_1 = ([ [1,2,3], [4,5,6] ])
(arr_1, 1, axis=1)
>>> [ [1,3], [4,6] ]
# 在2维度删除元素
arr_1 = ([ [[1,11],[2,22],[3,33]], [[4,44],[5,55],[6,66]] ])
(arr_1, 1, axis=2)
>>> [ [[1],[2],[3]], [[4],[5],[6]] ]
3.4 NumPy数组强变换
相对于列表和元组,NumPy的数组提供了更加灵活多变的数组形状变化。
(arr, newshape, order='C')函数可以不改变数据的条件下修改形状:
import numpy as np
arr_1 = ([ [1,2,3], [4,5,6] ])
arr_2 = arr_1.reshape(3,2)
print(arr_2)
>>> array([ [1, 2], [3, 4], [5, 6] ])
(order='C')返回一份数组拷贝,对拷贝所做的修改不会影响原始数组。
import numpy as np
arr_1 = ([ [1,2,3], [4,5,6] ])
arr_2 = arr_1 .flatten()
print(arr_2)
>>> array([1, 2, 3, 4, 5, 6])
arr_2 = arr_1 .flatten(order='F')
print(arr_2)
>>> array([1, 4, 2, 5, 3, 6])
arr_2[0]=-1
print(arr_1)
>>> array([ [1,2,3], [4,5,6] ])
(arr, order='C')展平数组元素,修改后会影响原数组:
import numpy as np
arr_1 = ([ [1,2,3], [4,5,6] ])
arr_2 = (arr_1)
arr_2[0] = -1
print(arr_1)
>>> array([ [-1,2,3], [4,5,6] ])
(arr, axes) 函数用于对换数组的维度:
import numpy as np
arr_1 = ([ [1,2,3], [4,5,6] ])
arr_2 = (arr_1)
print(arr_2)
>>> array([ [1, 4], [2, 5], [3, 6] ])