1. 程式人生 > >Python從菜鳥到高手(13):分片(Slicing)

Python從菜鳥到高手(13):分片(Slicing)

方式 ans 表示 獲取元素 nsh 通過 int 值類型 步長

分片操作是從序列A中獲取一個子序列B。序列A可以稱為父序列。從A中獲取B,需要指定B在A中的開始索引和結束索引,因此,分片操作需要指定兩個索引。

??由於字符串可以看做是字符的序列,所以我們可以用序列的這個分片特性截取子字符串。

??本例通過分片操作獲取一個Url的一級域名和完整的域名。

url = ‘https://geekori.com‘
print(url[8:15])                #  運行結果:geekori
print(url[8:19])                #  運行結果:geekori.com

程序運行結果如下圖所示。

技術分享圖片

??在上面的代碼中,使用url[8:15]來截取url中的“geekori”,其中8和15是url中的兩個索引。我們可以看到,兩個索引之間要使用冒號(:)分隔。可能有的讀者會發現,索引15並不是“i”的索引,而是“.”的索引,沒錯,在指定子序列結束索引時,要指定子序列最後一個元素的下一個元素的索引,因此,應該指定“.”的索引,而不是“i”的索引。

??那麽如果子序列的最後一個元素恰好是父序列的最後一個元素該怎麽辦呢?例如,url中的最後一個元素是“m”,如果要截取“geekori.com”,子序列的結束索引應該如何指定呢?其實子序列的結束索引只要指定父序列最後一個元素的索引加1即可。由於父索引最後一個元素“m”的索引是18,因此,要截取“geekori.com”,需要指定結束索引為19,也就是url[8:19]。

  1. 省略子序列的索引
  2. 首先看一個用分片截取數字序列的例子。

本例通過分片操作截取numbers序列中的某個子序列。

numbers = [1,2,3,4,5,6,7,8]
print(numbers[3:5])             #  運行結果:[4, 5]
print(numbers[0:1])             #  運行結果:[1]
print(numbers[5:8])             #  運行結果:[6, 7, 8]
print(numbers[-3:-1])               #  運行結果:[6,7]

程序運行結果如下圖所示。

技術分享圖片

??本例通過將結束索引設為0,獲取一個空序列。

numbers = [1,2,3,4,5,6,7,8]
print(numbers[-3:0])                    #  運行結果:[]

程序運行結果如下圖所示。

技術分享圖片

??Python語言規定,如果結束索引比開始索引晚出現,那麽就會返回空序列,在這裏索引0比索引-3晚出現。如果要使用負數作為索引,並且獲取的子序列的最後一個元素與父序列的最後一個元素相同,那麽可以省略結束索引,或結束索引用正整數。

本例使用負數作為開始索引,並省略結束索引。

numbers = [1,2,3,4,5,6,7,8]
print(numbers[-3:])                     # 省略了結束索引,運行結果:[6, 7, 8]
print(numbers[-3:8])                    # 結束索引用了正整數作為索引,運行結果:[6, 7, 8]

程序運行結果如下圖所示。

技術分享圖片

??這種省略索引的方式統一適用於開始索引。
本例省略了開始索引。

numbers = [1,2,3,4,5,6,7,8]
print(numbers[:3])                  # 截取父序列中前3個元素作為子序列,運行結果:[1, 2, 3]

程序運行結果如下圖所示。

技術分享圖片

??如果開始索引和結束索引都不指定,那麽會復制整個子序列。
??本例下面的代碼通過省略開始索引和結束索引,復制了整個序列。

numbers = [1,2,3,4,5,6,7,8]
print(numbers[:])                   # 復制整個序列,運行結果:[1, 2, 3, 4, 5, 6, 7, 8]

程序運行結果如下圖所示。

技術分享圖片

??在對序列分片時,默認的步長是1,也就是說,獲取的子序列的元素都是相鄰的。如果要獲取不相鄰的元素,就需要指定步長。例如,要獲取索引為1、3、5的元素作為子序列的元素,就需要將步長設為2。

??本例通過改變分片操作的步長,獲取元素不相鄰的子序列。

numbers = [1,2,3,4,5,6,7,8,9]
print(numbers[1:6:2])       # 指定步長為2,運行結果:[2, 4, 6]

程序運行結果如下圖所示。

技術分享圖片

??在上面的代碼中,使用numbers[1:6:2]獲取了索引為1、3、5的元素作為子序列的元素,其中2是步長,我們可以看到,開始索引、結束索引和步長之間都用冒號分隔(:)。

??其實,開始索引,結束索引和步長都是可以省略的。

本例在分片時指定步長,但省略了開始索引以及結束索引。

numbers = [1,2,3,4,5,6,7,8,9]
print(numbers[:7:2])    # 省略了開始索引,運行結果:[1, 3, 5, 7]
print(numbers[::2]) # 省略了開始索引和結束索引,運行結果:[1, 3, 5, 7, 9]
print(numbers[3::2])    # 省略了結束索引,運行結果:[4, 6, 8]

程序運行結果如下圖所示。

技術分享圖片

??步長不能為0,但可以是負數。如果步長為0,會拋出異常,如果步長是負數,分片會從序列的右側開始,這時開始索引要大於結束索引。

??在使用分片步長時,分別使用了負數和0。

numbers = [1,2,3,4,5,6,7,8,9]
# 步長為-2,從索引為8的元素開始,一直到索引為3的元素,運行結果:[9, 7, 5]
print(numbers[8:2:-2])  
print(numbers[8:2:-1])     # 步長為-1,運行結果:[9, 8, 7, 6, 5, 4]
print(numbers[1:6:0])      # 步長為0,會拋出異常

程序運行結果如下圖所示。

技術分享圖片

??在上面的代碼中,如果步長為負數,那麽分片的開始索引需要大於結束索引。例如,numbers[8:2:-2]表示從索引為8的元素開始,往前掃描,直到索引為2的元素的上一個元素,也就是索引為3的元素為止。
當然,如果使用負數作為步長,還有一些比較燒腦的用法,得出這些用法的分片結果,需要動一下腦筋。

??本例將負數作為分片步長。

numbers = [1,2,3,4,5,6,7,8,9]
#  步長為-3,從序列最後一個元素開始,一直到序列第一個元素結束,運行結果:[9, 6, 3]
print(numbers[::-3])        
#  步長為-2,從序列的最後一個元素開始,一直到索引為4的元素結束,運行結果:[9, 7, 5]
print(numbers[:3:-2])

程序執行結果如下圖所示。

技術分享圖片

??本例要求從Python控制臺輸入一個Url和一個數字n。然後對Url分片,獲取Url的Scheme和Host,最後根據這個數字生成一個包含1到n的序列,然後對該序列進行兩次分片,一次獲取序列中的所有奇數,一次獲取序列中的所有偶數,並分兩行錯位顯示。

url = input("請輸入一個Https網址:")
scheme = url[0:5]                   #  分片獲取Url中的Scheme
host = url[8:]                      #  分片獲取Url中的Host

print("scheme:", scheme)
print("host:",host) 

str = input("請輸入一個整數:")
n = int(str);

numbers = range(1,n)                # 產生包含1到n的數值類型的序列
numbers1 = numbers[0::2]            # 分片獲取序列中的奇數
numbers2 = numbers[1::2]            # 分片獲取序列中的偶數
for number in numbers1:             # 在第1行輸出所有的奇數
    print(number, end= " ")
print("")
print(" ",end="")
for number in numbers2:             # 在第2行錯位輸出所有的偶數
    print(number, end= " ")

程序運行結果如下圖所示。

技術分享圖片

《Python從菜鳥到高手》已經出版,開始連載了,購買送視頻課程

Python從菜鳥到高手(13):分片(Slicing)