天天看点

c++ list用法_Python高阶玩法干货:切片误区与基本用法python切片使用实例、应用技巧、基本知识点总结和需要注意事项:1、切片的基础用法常用的切片操作2、切片是伪独立对象3、切片可作为占位符

python切片使用实例、应用技巧、基本知识点总结和需要注意事项:

c++ list用法_Python高阶玩法干货:切片误区与基本用法python切片使用实例、应用技巧、基本知识点总结和需要注意事项:1、切片的基础用法常用的切片操作2、切片是伪独立对象3、切片可作为占位符

1、切片的基础用法

在python原生list中的运用

通常一个切片操作要提供三个参数[start:stop:step]

start是切片的起始位置

stop是切片的结束位置(不包括)

step可以不提供,默认值是1,步长值不能为0,不然会报错。

切片的书写形式:[i : i+n : m] ;其中,i 是切片的起始索引值,为列表首位时可省略;i+n 是切片的结束位置,为列表末位时可省略;m 可以不提供,默认值是1,不允许为0 ,当m为负数时,列表翻转。注意:这些值都可以大于列表长度。

ValueError: slice step cannot be zero

list=[1,2,3,4,5,6,7,8,9]
           
c++ list用法_Python高阶玩法干货:切片误区与基本用法python切片使用实例、应用技巧、基本知识点总结和需要注意事项:1、切片的基础用法常用的切片操作2、切片是伪独立对象3、切片可作为占位符

当step为正数时,以list[start]元素位置开始, step做为步长到list[stop_]元素位置(不包括)为止,从左向右截取。start和stop不论是正数还是负数索引还是混用都可以,但是要保证 list[stop]元素的【逻辑】位置,必须在list[start]元素的【逻辑】位置右边,否则取不出元素。

print(list[0:4])
           

[0, 1, 2, 3]

print(list[1:-1])
           

[1, 2, 3, 4, 5, 6, 7, 8]

print(list[-8:8])
           

[2, 3, 4, 5, 6, 7]

当 step 是负数时,以list[start]元素位置开始, step做为步长到list[stop]元素位置(不包括)为止,从右向左截取,要保证 list[stop]元素的【逻辑】位置

必须在list[start]元素的【逻辑】位置左边,否则取不出元素。

print(list[5:2:-1])
           

[5, 4, 3]

print(list[7:-7:-1])
           

[7, 6, 5, 4]

start和stop在符合虚拟的逻辑位置关系时,start和stop的绝对值是可以大于length的。

print(list[-12:5:2])
           

[0, 2, 4]

start和stop都是可以省略的,例如 list[:],被省略的默认由其对应左右边界起始元素开始截取。

print(list[:])
           

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

切片的基本含义是:从序列的第i位索引起,向右取到后n位元素为止,按m间隔过滤 。

li = [1, 4, 5, 6, 7, 9, 11, 14, 16]# 以下写法都可以表示整个列表,其中 X >= len(li)li[0:X] == li[0:] == li[:X] == li[:]== li[::] == li[-X:X] == li[-X:]li[1:5] == [4,5,6,7] # 从1起,取5-1位元素li[1:5:2] == [4,6] # 从1起,取5-1位元素,按2间隔过滤li[-1:] == [16] # 取倒数第一个元素li[-4:-2] == [9, 11] # 从倒数第四起,取-2-(-4)=2位元素li[:-2] == li[-len(li):-2]== [1,4,5,6,7,9,11] # 从头开始,取-2-(-len(li))=7位元素# 步长为负数时,列表先翻转,再截取li[::-1] == [16,14,11,9,7,6,5,4,1] # 翻转整个列表li[::-2] == [16,11,7,5,1] # 翻转整个列表,再按2间隔过滤li[:-5:-1] == [16,14,11,9] # 翻转整个列表,取-5-(-len(li))=4位元素li[:-5:-3] == [16,9] # 翻转整个列表,取-5-(-len(li))=4位元素,再按3间隔过滤# 切片的步长不可以为0li[::0]  # 报错(ValueError: slice step cannot be zero)
           

上述的某些例子对于初学者(甚至很多老手)来说,可能还不好理解。我个人总结出两条经验:

(1)牢牢记住公式[i : i+n : m] ,当出现缺省值时,通过想象把公式补全;

(2)索引为负且步长为正时,按倒数计算索引位置;索引为负且步长为负时,先翻转列表,再按倒数计算索引位置。

c++ list用法_Python高阶玩法干货:切片误区与基本用法python切片使用实例、应用技巧、基本知识点总结和需要注意事项:1、切片的基础用法常用的切片操作2、切片是伪独立对象3、切片可作为占位符

常用的切片操作

在某个位置插入元素

list[3:3] = "a"print(list)
           

[0, 1, 2, ‘a’, 3, 4, 5, 6, 7, 8, 9]

list[5:5] = ["a","b"]print(list)
           

[0, 1, 2, 3, 4, ‘a’, ‘b’, 5, 6, 7, 8, 9]

2、切片是伪独立对象

切片操作的返回结果是一个新的独立的序列。以列表为例,列表切片后得到的还是一个列表,占用新的内存地址。

c++ list用法_Python高阶玩法干货:切片误区与基本用法python切片使用实例、应用技巧、基本知识点总结和需要注意事项:1、切片的基础用法常用的切片操作2、切片是伪独立对象3、切片可作为占位符

当取出切片的结果时,它是一个独立对象,因此,可以将其用于赋值操作,也可以用于其它传递值的场景。但是,切片只是浅拷贝,它拷贝的是原列表中元素的引用,所以,当存在变长对象的元素时,新列表将受制于原列表。

li = [1, 2, 3, 4]ls = li[::]li == ls # Trueid(li) == id(ls) # Falseli.append(li[2:4]) # [1, 2, 3, 4, [3, 4]]ls.extend(ls[2:4]) # [1, 2, 3, 4, 3, 4]# 下例等价于判断li长度是否大于8if(li[8:]):    print("not empty")else:    print("empty")# 切片列表受制于原列表lo = [1,[1,1],2,3]lp = lo[:2] # [1, [1, 1]]lo[1].append(1) # [1, [1, 1, 1], 2, 3]lp # [1, [1, 1, 1]]
           

由于可见,将切片结果取出,它可以作为独立对象使用,但是也要注意,是否取出了变长对象的元素。

3、切片可作为占位符

切片既可以作为独立对象被“取出”原序列,也可以留在原序列,作为一种占位符使用。

在写《详解Python拼接字符串的七种方式》的时候,我介绍了几种拼接字符串的方法,其中三种格式化类的拼接方法(即 %、format()、template)就是使用了占位符的思想。对于列表来说,使用切片作为占位符,同样能够实现拼接列表的效果。特别需要注意的是,给切片赋值的必须是可迭代对象。

li = [1, 2, 3, 4]# 在头部拼接li[:0] = [0] # [0, 1, 2, 3, 4]# 在末尾拼接li[len(li):] = [5,7] # [0, 1, 2, 3, 4, 5, 7]# 在中部拼接li[6:6] = [6] # [0, 1, 2, 3, 4, 5, 6, 7]# 给切片赋值的必须是可迭代对象li[-1:-1] = 6 # (报错,TypeError: can only assign an iterable)li[:0] = (9,) #  [9, 0, 1, 2, 3, 4, 5, 6, 7]li[:0] = range(3) #  [0, 1, 2, 9, 0, 1, 2, 3, 4, 5, 6, 7]
           

上述例子中,若将切片作为独立对象取出,那你会发现它们都是空列表,即 li[:0]==li[len(li):]==li[6:6]==[] ,我将这种占位符称为“纯占位符”,对纯占位符赋值,并不会破坏原有的元素,只会在特定的索引位置中拼接进新的元素。删除纯占位符时,也不会影响列表中的元素。

c++ list用法_Python高阶玩法干货:切片误区与基本用法python切片使用实例、应用技巧、基本知识点总结和需要注意事项:1、切片的基础用法常用的切片操作2、切片是伪独立对象3、切片可作为占位符

与“纯占位符”相对应,“非纯占位符”的切片是非空列表,对它进行操作(赋值与删除),将会影响原始列表。如果说纯占位符可以实现列表的拼接,那么,非纯占位符可以实现列表的替换。

li = [1, 2, 3, 4]# 不同位置的替换li[:3] = [7,8,9] # [7, 8, 9, 4]li[3:] = [5,6,7] # [7, 8, 9, 5, 6, 7]li[2:4] = ['a','b'] # [7, 8, 'a', 'b', 6, 7]# 非等长替换li[2:4] = [1,2,3,4] # [7, 8, 1, 2, 3, 4, 6, 7]li[2:6] = ['a']  # [7, 8, 'a', 6, 7]# 删除元素del li[2:3] # [7, 8, 6, 7]
           

切片占位符可以带步长,从而实现连续跨越性的替换或删除效果。需要注意的是,这种用法只支持等长替换。

li = [1, 2, 3, 4, 5, 6]li[::2] = ['a','b','c'] # ['a', 2, 'b', 4, 'c', 6]li[::2] = [0]*3 # [0, 2, 0, 4, 0, 6]li[::2] = ['w'] # 报错,attempt to assign sequence of size 1 to extended slice of size 3del li[::2] # [2, 4, 6]