python中神奇的切片
By 青衣极客 Blue Geek In 2019-09-16
使用python进行数据分析的朋友或许没有不知道“切片”这种操作的。使用“切片”不仅能够让代码更加简洁,也能在很大程度上提升程序运行的性能。这里我们简要介绍一些python中最常用的“切片”操作的使用方式。对于一些第三方模块,也常常提供类似的使用方法以提升效率。
import os
import numpy as np
1. 什么是切片?
切片就是从一个元素序列中获取子集。如果一种编程语言没有提供特殊的切片操作, 这需要自己编写程序完成这种操作。对于一个python列表数据,我们想要从中获取一些子元素组成的列表,当然可以使用最直观粗暴的方式完成。
a_list = list(range(10))
print('a_list =', a_list)
# 获取a_list中第5到第8个元素
b_list = [x for idx, x in enumerate(a_list) if idx >= 4 and idx <= 7]
print('b_list =', b_list)
# 获取a_list中索引为偶数的元素
c_list = [x for idx, x in enumerate(a_list) if idx % 2 == 0]
print('c_list = ', c_list)
a_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b_list = [4, 5, 6, 7]
c_list = [0, 2, 4, 6, 8]
这样虽然也能实现需求,但是,无论从可读性还是效率方便都是不高的。这时python提供的“切片”操作就有用武之地了。
# 使用python中的切片操作
da_list = a_list[4:8]
db_list = a_list[::2]
print('da_list = ', da_list)
print('db_list = ', db_list)
da_list = [4, 5, 6, 7]
db_list = [0, 2, 4, 6, 8]
从以上两种方式的实现可以看出,“切片”比直接粗暴的实现要好很多。开发者在知晓“切片”之后对第一种方式的实现是从心底排斥的。
2. 怎样设置切片的参数?
切片确实比自己手动用循环和分支结构编写程序要方便很多,而且代码简洁。接下来就需要了解切片的参数以便灵活运用切片了。切片参数的完成格式如下:
start_index : end_index : step
前闭后开,包含start_index, 不包含end_index。比如下面的例子所示:
# 获取索引3到索引7之间(前闭后开)索引为奇数的元素
b_list = a_list[3:7:2]
print('b_list = ', b_list)
b_list = [3, 5]
在实际开发中,使用这种完整形式的情况反而不太多,毕竟需要多写几个字符对程序员而言实在是不能忍受的事情。而且,在一些情况下省略参数能够避免对一些边界条件的繁冗判断。下面就展示几种省略参数的情况。
(1) 省略start_index,则该参数默认为0
# 省略start_index,则该参数默认为0
c_list = a_list[:7:2]
print('c_list = ', c_list)
c_list = [0, 2, 4, 6]
(2) 省略end_index,则该参数默认包含序列最后一个元素
# 省略end_index,则该参数默认包含序列最后一个元素
d_list = a_list[3::2]
print('d_list = ', d_list)
d_list = [3, 5, 7, 9]
(3) 省略step,则该参数默认为 1
# 省略step,则该参数默认为 1
e_list = a_list[3:7]
print('e_list = ', e_list)
e_list = [3, 4, 5, 6]
(4) 全都省略,则表示取所有元素
# 全都省略,则表示取所有元素
f_list = a_list[:]
print('f_list = ', f_list)
f_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3. 神奇的效果
以上省略一些参数是常规用法,还有一些特殊的参数设置往往能让“切片”操作看起来非常神奇。这里就给出几个神奇效果的例子。
(1) 取倒数第4个到倒数第1个元素
# 取倒数第4个到倒数第1个元素
b_list = a_list[-4:-1]
print('b_list = ', b_list)
b_list = [6, 7, 8]
(2) 取序列元素的倒序
# 取序列元素的倒序
c_list = a_list[::-1]
print('c_list = ', c_list)
c_list = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
(3) 取索引为7到索引为2的元素
# 取索引为7到索引为2的元素
d_list = a_list[7:2:-1]
print('d_list = ', d_list)
d_list = [7, 6, 5, 4, 3]
(4) 取倒数第1个到倒数第4个元素
# 取倒数第1个到倒数第4个元素
e_list = a_list[-1:-4:-1]
print('e_list = ', e_list)
e_list = [9, 8, 7]
大家可以想想,这几个神奇效果的例子,如果不使用这种“切片”的方式实现,那么该如何实现呢?实现方法可能五花八门,但基本可以肯定比较复杂。这也是切片受大家喜闻乐见的原因。
4. numpy中的切片
numpy虽然是第三方模块,但其提供的切片操作与python本身的操作非常相似,而且numpy也是使用python进行数据分析或者机器学习所必不可少的工具。这里也简要介绍一些numpy中的切片。首先需要创建一个numpy数组:
arr = np.array(range(25))
arr = np.reshape(arr, (5,5))
print('arr =', arr)
arr = [[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
然后就可以对这个数组进行切片操作了。
(1) 取第2到第4行
# 取第2到第4行
b_arr = arr[2:5, :]
print('b_arr = ', b_arr)
b_arr = [[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
(2) 取第2到第4列
# 取第2到第4列
c_arr = arr[:, 2:5]
print('c_arr = ', c_arr)
c_arr = [[ 2 3 4]
[ 7 8 9]
[12 13 14]
[17 18 19]
[22 23 24]]
(3) 二维切片, 第一个是行切片,第二个是列切片
d_arr = arr[0:4:2, -1:-3:-1]
print('d_arr = ', d_arr)
d_arr = [[ 4 3]
[14 13]]
(4) 省略号的使用
# 省略号
e_arr = arr[0:2, ...]
print('e_arr = ', e_arr)
e_arr = [[0 1 2 3 4]
[5 6 7 8 9]]
省略号的这种方式在高维张量的切片操作中常常使用。
Python中最常用的切片形式基本都提到了,看到学到,一直到最终在自己的项目中使用才算是得到,希望大家都能通过“切片”的使用提升开发效率。
CHANGELOG
- 2020-04-07 加入解说文本

COMMENT
博客评论区功能由Github Issue提供,提交Issue时请以本文标题为话题。
"BG04-python中神奇的切片"