谈谈Python中列表、元组和数组的区别和骚操作

谈谈Python中列表、元组和数组的区别和骚操作

一、列表(List)

1.列表的特点

  • 列表是以方括号“[]”包围的数据集合,不同成员以“,”分隔。如 L = [1,2,3], 列表a有3个成员。
  • 列表是可变的数据类型【可进行增删改查】,列表中可以包含任何数据类型,也可以包含另一个列表。如: L = [1,2,[3,4]],列表L有3个成员,最后一个成员为一个列表。
  • 列表可以通过序号(索引)访问其中成员,成员序号从0开始,如:a[0]=1。
  • 列表没有shape,计算列表中成员(元素)的个数,成员以最外层的[ ]中的逗号“,”来分隔,计算方式是len(L)=3, L = [1,2,[3,4]] ,没有数组中的a.shape操作。
  • 空列表(0个元素的列表):L=[], 一个元素的列表:L=[1], 多个元素的列表L=[1,2,3]

2.列表运算符

列表对+ 和 * 的操作符与字符串操作类似 ,列表之间可以使用 + 号和 * 号进行运算。+号用于组合列表,*号用于重复列表,运算之后会生成一个新的列表,如下图所示:

3.列表内置的函数和方法

列表操作补充:

#列表操作补充--切片操作
# 创建空列表
a = []
# 创建一个非空列表example
example = [0,1,2,3,4,5,6,7,8,9]  
#切片打印某一区间 左闭右开(包含左边开始序号的成员start,不包括结束序号的成员end)  
print(example[4:8])  # [4, 5, 6, 7]
#想包含最后一个  
print(example[4:])   # [4, 5, 6, 7, 8, 9]
#包含首个  
print(example[:8])  # [0, 1, 2, 3, 4, 5, 6, 7]
print(example[:])  
#第三个参数为步长,左闭右开  
print(example[1:8:2])  # [1, 3, 5, 7] 
#倒序输出  
print(example[::-1])  
#列表合并  
a = [1,2,3]  
b = [4,5,6]  
print(a+b)
ex = [1,2,3,4,5,6]
ex[4:]=[9,8,7] # 从第四个元素开始将剩余元素替换  
print(ex) #将56换为987
# 定义包含不同数据类型的列表
list4=[123,["das","aaa"],234]
# in只能判断一个层次的元素
"aaa" in list4      # False
# 但是可以选中列表中的列表进行判断
"aaa" in list4[1]   # True 
# 获取列表中的某个元素
print(list4[1][1])  # 'aaa'  


二、元组(Tuple)

1.元组的特点

  • 元组是以圆括号“()”包围的数据集合,括号()可以省略,不同成员(元素)以逗号“,”分隔,如:T=(1,2,3)。
  • 元组是不可变序列,即元组一旦创建,元组中的数据一旦确立就不能改变,不能对元组中中的元素进行增删改操作,因此元组没有增加元素append、修改元素、删除元素pop的相关方法,只能通过序号(索引)访问元组中的成员,元组中的成员的起始序号为0,如:T[0]=1, T=(1,2,3)。
  • 元组中可以包含任何数据类型,也可以包含另一个元组,如:T=(1,2,3,('a','b'))
  • 空元组(没有元素的元组):T=(),含1个元素的元组:T=(1,),注意有逗号,多个元素的元组:T=(1,2,3)
  • 任意无符号的对象,以逗号隔开,默认为元组,如下:

2.元组运算符

与字符串和列表一样,元组之间可以使用+号和*号进行运算,+号用于组合元组,*号用于重复元组,运算之后会生成一个新的元组,如下图所示:

3.元组内置的函数

4.元组操作补充访问元组

访问元组
o =('a','b','c',('d1','d2'))
print o[0]    #a
print o[3][0] #d1
# 索引访问
print(o[0:2])  #
age=22
name='sandra'
print('%s is %d years old'%(name,age)) # sandra is 22 years old
元组中的元素值是不允许修改的,但是我们还可以对元组进行拼接
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
# 创建一个新的元组
tup3 = tup1 + tup2
print tup3;
del tup1
#通过切片方法添加
a=(1,2,3,4,5,6)
a=a[:2]+(10,)+a[2:] # 在元组的第2个元素后面添加一个元组(10,)
print(a)  # (1, 2, 10, 3, 4, 5, 6)

三、数组(Array-numpy)


1.数组(numpy array)的特点

准确来说Python中是没有数组类型的,只有列表(list)和元组(tuple), 数组是numpy库中所定义的,所以在使用数组之前必须下载安装numpy库。 python中的list是python的内置数据类型,list中的数据类不必相同的,而array的中的类型必须全部相同。在list中的数据类型保存的是数据的存放的地址,简单的说就是指针,并非数据,这样保存一个list就太麻烦了,例如list1=[1,2,3,'a']需要4个指针和四个数据,增加了存储和消耗cpu。numpy中封装的array有很强大的功能,里面存放的都是相同的数据类型。

  • numpy array 是以方括号“[]”包围的数据集合,不同成员以空格“ ”分隔。如 a=[1 2 3 4]
  • numpy array 的数据成员必须是相同数据类型属性,不同于列表和元组
  • numpy array 数组是可以多维的,而列表和元组是一维的,数组的每个维度之间以换行分隔开,单个维度内的数组成员也以换行分隔开,每个并列(单个)维度内的成员个数需要一致,不同维度的成员个数可以不一样。ru
  • numpy array 通过索引号(下标)来访问数组元素,数组每个维度的元素的起始索引*号为0,如:a[1][1] = 2 , a = [[0 1] ,或者以逗号分隔的整数表示元素的维数和索引,如:arr[1,1]=2

[1 2]]

  • numpy array 有很多可以直接使用的函数
  • numpy array有形状大小shape,即维度,获取的两种方式np.shape(a) 或者 a.shape,即可得到数组的大小。


2.数组的创建

安装numpy库(pip或者conda)

导入numpy库(通过import关键字导入):import numpy as np

创建数组的几种方式:

Numpy 用于处理数组,Numpy中的数组对象称为ndarray,我们使用array()函数创建一个Numpy的ndarray对象,我们可以将列表、元组或者任何类似数组的对象传递给array()方法,array方法会将它们转换为ndarray。


import numpy as np
# 方法一:使用列表创建numpy数组
# 列表转数组
# 列表中有列表时,转数组时,首先将逗号“,”全部变为空格“ ”,以最外层[]中的逗号“,”以换行分开成为数组的第一维度的不同成员(元素),其他类推
a =np.array( [[1,2,3],[4,5,6]] )
print(a)
# [[1 2 3]
[4 5 6]]


# 方法二 :使用元组创建numpy数组
# 元组转数组
# 元组中有元组时,转数组时,首先将逗号“,”全部变为空格“ ”,以最外层[]中的逗号“,”以换行分开成为数组的第一维度的不同成员(元素)
arr = ((1,2),(3,4))
arr0 =np.array(arr)
print(arr0)
# [[1 2]
[3 4]]


3.数组中的维

数组中的维是数组深度(嵌套数组)的一个级别,嵌套数组是将数组作为元素的数组,即数组中有数组。

(1)0-D维数组
0维数组,也称作标量,是指数组中只有一个元素,数组的值只有一个
a= 61
arr = np.array(a)
print(a) # 61
print(type(arr)) # <class 'numpy.ndarray'>
print(arr.shape) # ()
(2)1-D维数组
一维数组,是指元素为0-D数组的数组,也就是由多个元素值构成的数组
a = [61,62,63]
arr = np.array(a)
print(arr) # [61 62 63]
print(arr.type) # (3,)
(3)2-D维数组
二维数组,它的元素为一维数组,它是一维数组的数组,通常用于表示矩阵或者二阶张量,在Numpy库中又一个专门用于矩阵运算的完整子模块,numpy.mat。
arr = np.array([[1, 2, 3], [4, 5, 6]]) # 列表转数组,数组的第一维度元素以最外层列表元素以行分隔
print(arr) # [[1 2 3]
[4 5 6]]


(3)3-D维数组
三维数组,它的元素为二维数组,它是二维数组的数组。
# 用两个二维数组,创建一个三维数组
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(arr) # [[[ 1 2 3]
[ 4 5 6]]


[[7 8 9]
[10 11 12]]]
print(arr.shape) # (2,2,3) # 数组每个维度的元素个数是shape的由外到内,如:第一维2个元素是:[[ 1 2 3] 和 [[7 8 9]
[ 4 5 6]] [10 11 12]]

(4)如何得到数组的维数?
NumPy 数组提供了 ndim 属性,该属性返回一个整数,该整数会告诉我们数组有多 少维,检查数组有多少维:
a = np.array(42)
b = np.array([1, 2, 3, 4, 5])
c = np.array([[1, 2, 3], [4, 5, 6]])
d = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])
print(a.ndim) # 0
print(b.ndim) # 1
print(c.ndim) # 2
print(d.ndim) # 3

(5)创建更高维的数组
数组可以拥有任意数量的维,在创建数组时,可以使用 ndmin 参数定义维数。
# 创建一个有5个维度的数组,并验证它拥有5个维度:
arr = np.array([1, 2, 3, 4], ndmin=)
print(arr) # [[[[[1 2 3 4]]]]]
print('number of dimensions :', arr.ndim) # number of dimensions : 5

说明:在这个5维数组中,最里面的一维,也就是第5个维度,有4个元素1234,第四个维度 有1个元素作为向量[1 2 3 4],第三个维度的元素是矩阵[[1 2 3 4]],也就是元素为2维数组,第2维度有1个元素是3维数组,第一个维度有1个元素,该元素是四维数组。

4.数组中的索引和裁切

(1)访问数组元素
 数组索引等同于访问数组元素,我们通过引用索引号来访问数组元素,Numpy中的数组的索引以0开始,即第一个元素的索引为0.第二个元素的索引为1、
 # 一维数组
 arr = np.array([1, 2, 3, 4])
 print(arr[1]) # 2
 # 二维数组或者更高维数组
 要访问二维数组或者更高维数组中的元素,我们可以使用逗号分隔的整数表示元素的维数和索引或者用数组的每个维度的索引号。
  arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])
  print(arr[1, 4])  # 10 表示第一维度中的第2个元素(即[6,7,8,9,10])的第5个元素
  print(arr[1][4]) # 10
  更高维类似
 # 使用负索引从尾开始访问数组
   arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])
   print(arr[1,-1])  # 10
(2)数组的裁切(相当于列表和元组的切片)
 Python中的裁切是指将元素从一个给定的索引带到另一个给定的索引,也就是切片的意思,以冒号“:”来传递,包含开始索引start,但是不包含结束索引end。
 我们像这样定义切片而不是索引:[start:end]。
 我们还可以定义步长,如下所示:[start:end:step]。
 如果我们不设置 start,则将其视为 0,即从索引号为0的元素开始索引。
 如果我们不设置 end,则视为该维度内数组的长度,即一直索引到该维度的最后一个元素。
 如果我们不设置start和end,则视为从索引号0的元素开始一直到最后一个元素
 如果我们不设置 step,则视为 1。
 # 从下面的数组中裁切索引 1 到索引 5 的元素
 arr = np.array([1, 2, 3, 4, 5, 6, 7])
   print(arr[1:5]) # [2 3 4 5]
   print(arr[:4])  # [1 2 3 4]
 # 设置步长剪切
 print(arr[1:5:2]) # [2 4]
 # 返回数组中相隔的元素
 print(arr[::2]) #[1,3,5,7]
 # 数组的负裁切
 使用减号运算符从末尾开始引用索引:
   arr = np.array([1, 2, 3, 4, 5, 6, 7])
   print(arr[-3:-1])  # [5 6]
 # 二维数组的裁切
 # 从第二个元素开始,对从索引 1 到索引 4(不包括)的元素进行切片
 arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
   print(arr[1, 1:4])  # [7 8 9],即 第一维度的第二个元素(即[6, 7, 8, 9, 10])的索引号从1到4(不包括4)的元素
 #从两个元素中返回索引 2:
   arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
   print(arr[0:2, 2]) # [3 8],即第一维度的第1个元素和第2个元素的各自的索引号为2的元素
 #从两个元素裁切索引 1 到索引 4(不包括),这将返回一个 2-D 数组:
   arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
   print(arr[0:2, 1:4])  # [[2 3 4] ,即维度的索引从0:2(2不包括)的元素 的各自的索引号从1到
                                    [7 8 9]]
4(不包括4)的元素
 

总结:列表和元组都可以转换为数组,列表是可变序列,有增加删除修改元素值的方法,元组是不可序列,列表和元组没有shape属性,它的大小是元素的个数,数组有形状shape,有shape属性,可以通过array.shape获取数组的形状大小shape,不管是列表、元组、数组的索引切片,都是左闭右开形式。我们可以通过print(type(x))来判别X是列表还是元组或者是数组。

附加:

# 1.两个列表转数组和数组的转置
a = [1,2]
print(len(a))
b = [3,4]
print(len([a,b])) # 2 列表元素个数,以最外层的[],中的逗号分开
# 单列表转数组时,将逗号消除
K = np.array(b)
print(K)
#显示数组的维度的两种方法: print(np.shape(h)) 或者print(h.shape)
print(K.shape)
print(np.shape(K))
# 一维数组转置是其本身
print(np.array(b).T) 
# 列表中有列表时,转数组时,将逗号消除,每个列表以换行分开
c = np.array([a,b])
print(c)
[[1 2]
[3 4]]
# 二维数组转置行和列交换
d = c.T
[[1 3]
[2 4]]
print(d)
# 2.单个列表转数组
e = [[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]]
print(type(e)) # <class 'list'>
f = np.array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
print(type(f))  # <class 'numpy.ndarray'>
print(f)
[[ 0  1  2  3  4]
[ 5  6  7  8  9]
[10 11 12 13 14]
[15 16 17 18 19]]
# 数组的转置 行变成列 列变成行
print(f.T)
[[ 0  5 10 15]
[ 1  6 11 16]
[ 2  7 12 17]
[ 3  8 13 18]
[ 4  9 14 19]]
# 3. 列表转数组的拼接
g = [[10,20]]
h = [[1,0],[2,0],[3,0],[4,0]]
score = np.array(g)
boundingbbox = np.array(h)
print(score)
print(boundingbbox)
print(np.shape(score))
print(np.shape(boundingbbox))
print("\n")
M = score.T
N = boundingbbox.T
print(np.shape(M))
print(np.shape(N))
print(M)