Python的序列切片

    xiaoxiao2024-07-27  9

           Python提供了一种把序列切成小块的操作,称为切片(slice)操作,其本质是访问由序列中的某些元素所构成的子集。Python的序列数据结构都支持切片操作,如列表、元组、字符串等,切片操作可以说是日常应用中最常使用的Python特性之一。 (1)基本写法 sequence[start : end] sequence:表示序列,可以是列表、字符串、元组等; start:起始索引; end:结束索引。 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]b = a[0:5]c = a[:]d = a[5:15]print('a=', a, 'b=', b, 'c=', c, 'd=', d) 输出结果: a= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] b= [1, 2, 3, 4, 5] c= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] d= [6, 7, 8, 9, 10] 可以看出:        1)序列a没有变化,说明切片(slice)操作不改变原序列,而是生成一个新序列;        2)序列b的结果说明从头切片的话,索引值是从0开始的,另外start所指元素在切片结果内,而end所指元素则不包括在切片结果中,说明切片[start:end]是一个半闭区间        3)序列c结果说明从头切片的话,start索引值0可以省略,如果取到序列末尾,end也应该省略这样更清爽;        4)序列d结果说明索引范围不能越过序列本身边界,越过边界自动取边界值(Python3特性,在Python2会报错)。 (2)负值索引        若要从序列尾部向前算,则可以用负值表示相关偏移量。 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]b = a[:-1]c = a[-3:]print('b=', b, 'c=', c) 输出结果: b= [1, 2, 3, 4, 5, 6, 7, 8, 9] c= [8, 9, 10] 可以看出:        1)序列b比a少了最后一个元素,说明:-1表示最后一个元素        2)序列c结果表明:用-n代表倒数第n个元素,并且即使start索引是负数,切片顺序也是从前往后的 (3)反向和步进操作        除了基本写法外,Python还提供了sequence[start : end : stride]的写法,以实现步进式切割。看示例: s = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]a = s[::2]b = s[::-1]c = s[::-2]print('a=', a, 'b=', b, 'c=', c) 输出结果: a= [1, 3, 5, 7, 9] b= [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] c= [10, 8, 6, 4, 2]       可以看出:        1)序列a为序列s每隔2个元素进行取值,说明有stride的话按步进值间隔取序列中的元素;        2)序列b与序列s为反向,说明步进值为负值的话,实施的是反向操作,从序列末尾从后往前取元素。        3)序列c的结果说明使用负数布进值,除了按照反向操作外,也按照数字大小间隔取元素。 一般的应用情况下,与正向切片相比,反向切片和步进操作使用相对较少,但需要用的话,是非常好用且异常简洁的。看一个反向操作的经典应用:回文字符串判断 回文字符串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。 先看C语言的经典实现: bool fun(char str[]){ int i, j, n; n = strlen(str); for (i = 0, j = n-1; i <= (n-1)/2; i++, j--) { if (str[i] != str[j]) break; } if i > j return True; else return False;}再看Python中利用反向切片操作的实现,异常简洁: def fun(str): return str == str[::-1] (4)不要同时指定start,end和stride        按照《Effective Python》一书中的说法,切片操作既有start和end,又有stride的话,可能会令人费解,牺牲了可读性,尤其是有负值索引和负的步进值情况下。看示例: s = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]a = s[-2:2:-2]print(a) 输出结果: a= [9, 7, 5]        上例意思是从序列s倒着数第二个元素(包含)到序列s正着数第二个元素(不包含)之间的范围(注意切片操作范围是半闭区间)按步进值2进行反向切片,确实有点绕口,但也还算好懂。        改进方式可以考虑使用两条赋值语句代替,具体方法可是先做范围切片,再做步进切片,也可以先做步进切片,再做范围切片。个人认为先范围再步进的方法更好。 s = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]a = s[-2:2:-2]b = s[3:len(s)-1]c = b[::-2]print('a=', a, 'c=', c) 输出结果: a= [9, 7, 5] c= [9, 7, 5]        上例中b和c先对s做范围切割,再做步进切割。        实际工作中如果思路清晰,切片使用熟练,同指定start,end和stride无不妥,毕竟就3个参数而已。
    转载请注明原文地址: https://ju.6miu.com/read-1291097.html
    最新回复(0)