Python中二维数据(数组、列表)索引和切片的Bug

Python中有关数据结构索引和切片引起的Bug

一维数据索引和切片

一维数组

对于一维数据进行索引和切片操作,大家都比较熟悉通过下面代码进行实现

python 复制代码
import numpy as np
data = np.random.randn(5)
print(data)
print(data[2:5])  #一维数组切片操作,获取索引2到4的数据
print(data[3])   #一维数组索引操作,获取索引为3的数据

一维列表

对于一维列表元组等相关结果的索引和切片操作,与一维数组类似

python 复制代码
ls = [1, 2, 3, 4, 5]
print(ls)
print(ls[3:5]) #一维列表切片操作,获取索引2到4的数据
print(ls[3])  #一维列表索引操作,获取索引为3的数据

二维数据的索引和切片

对于二维数据的索引和切片就有一些需要注意的事项了,如果一不小心可能会出现意料之外的Bug

二维数组

python 复制代码
import numpy as np
data = np.random.randn(5, 5)
print(data)
print(data[1:3, 2:4])  #二维数组切片操作,获取索引1到2行2到3列的数据
print(data[3, 2])   #二维数组索引操作,获取索引为3行2列的数据
print(data[3][2])   #二维数组索引操作,获取索引为3行2列的数据
print(data[1:3])    #二维数组切片操作,获取索引为1到2行所有列的数据
print(data[:, 2:4])  #二维数组切片操作,获取索引为2到3列的所有行数据
print(data[1:3][2:4]) #想要获取1到2行和2到3列数据,单数会引发bug

上面就是二维数组索引和切片的大部分操作,对于索引来说可以使用data3, 2也可以使用data32操作,这两个获取的结果是一致的,那对于切片操作来说为啥data1:3, 2:4和操作data1:32:4不仅获取的结果不一致而且data1:32:4获取到的数据为空。对于初学者来说可能很难理解这样的情况,不知道bug的原因。但是换个索引行列data1:30:2会获得下面结果

这个情况就比较让人费解了,索引1到2行2到3列的数据获取为空,索引1到2行0到1列反而可以得到数据。问题是二维数组的大小为5x5,无论哪种索引都没超过数组范围啊。但是仔细查看索引数据data1:30:2发现得到的并不是1到2行0到1列的数据,而是1到2行所有列的数据。什么原因导致的呢?因为1:30:2这样的索引方式并不是向我们想的那样获取1到2行0到1列的数据。而是两次行索引操作,第一次获取1到2行所有列数据,数据大小为2x5,第二次获取0到1行的所有列数据。这样并没有列索引的操作,因此无法获取我们想要的数据。那为啥data1:32:4索引的数据为空呢?因为第一次行索引得到2x5大小的二维数组,第二次行索引获取2到3行的数据超出了数据大小范围,因此获得的数据为空。所以对于二维数组data1:32:4不是对相应的行列索引切片,而是进行了两次行切片 。切记不要搞错,不然获取数据为空引发的bug还好解决,万一获取错误数据可能就不容易发现Bug了。

那为何进行索引操作data3, 2和data32都可以正常获取数据呢?(PS:要不是有这样一个索引操作,估计大家就不会使用类似的切片操作了)因为第一次行索引获得第3行数据,大小为1x5,第二次获取第3行中的第2个数据因此可以正常获取到3行2列的数据。

二维(错误)列表

对于二维列表或者元组进行索引或者切片操作,可能会引发以上Bug

python 复制代码
    zarten = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]]
    print(zarten)
    print(zarten[3][2])
    print(zarten[1:3][0:2])
    print(zarten[1:3, 2:4])  #错误切片操作
    print(zarten[3, 2])      #错误索引操作

为何二维列表或元组进行二维数组类似的索引和切片操作就会出现以上报错,因为列表和元组没有二维数据,有同学觉得上面5x5的不就是二维列表吗?其实不是,这只是个列表中的列表,并无行列区分。比如列表中每个列表的元素个数可以不同,第一个列表中可以有5个元素,第二个列表中可以有3个元素等等,因此列表、元组并不能像我们认为的二维数组那样进行行列索引、切片操作。但是如果列表中的每个列表元素个数以及数据类型都一致,可以通过将列表转换为NumPy数组进行行列索引、切片操作。

python 复制代码
import numpy as np
data = np.array(data)

祝好~

相关推荐
myenjoy_19 分钟前
串口采集与 Modbus RTU——字节流里的时间敏感博弈
网络·python·网络协议·tcp/ip
FlyWIHTSKY16 分钟前
React 19 + Next.js 16(App Router)项目中集成 MSW
开发语言·javascript·vue.js
易舟云财务软件18 分钟前
财务 AI Python 实战:从自动化报表到智能风控的应用场景
人工智能·python·自动化
武雄(小星Ai)18 分钟前
一个模型干五件事:拆解 NVIDIA Cosmos 3 的物理 AI 全模态架构
人工智能·python·agent
Mr.Daozhi21 分钟前
跨境电商选品完整流水线:Google Trends筛词+Meta广告分析,CLI工具设计实战
开发语言·爬虫·python·跨境电商·工具链·选品
多彩电脑22 分钟前
Swift里字符串的索引
开发语言·swift
SoftLipaRZC22 分钟前
C语言预处理详解:从宏定义到条件编译
c语言·开发语言
会周易的程序员22 分钟前
C++ 对象池深度解析:架构设计与实现原理
开发语言·c++·物联网·iot·aiot
L_090727 分钟前
【C++】智能指针
开发语言·c++·智能指针
程序猿乐锅28 分钟前
【苍穹外卖|Day02】后台接口自测闭环:Token、DTO 与 yml 配置
java·开发语言