網(wǎng)站首頁 編程語言 正文
1. 前言
在剛學python時候,我們都知道字符串(String)、列表(list)和元組(tuple)序列化數(shù)據(jù)類型支持切片操作。
# slice operation TUPLE = (1,2,3,4) LIST = [1,2,3,4] STRING = "1234" print("TUPLE[1:3]:",TUPLE[1:3]) print("LIST[1:3]:",LIST[1:3]) print("STRING[1:3]:",STRING[1:3]) # output TUPLE[1:3]: (2, 3) LIST[1:3]: [2, 3] STRING[1:3]: 23
通過上述例子,我們可以快速使用“區(qū)間”的方式截取到想要的數(shù)據(jù)。那么最后一位始終都沒有取到?接下來,我們對熟悉的切片操作進行系統(tǒng)學習。
2. 什么是切片
2.1 切片概述
Python 序列數(shù)據(jù)類型索引從左到右開始是從0開始,依次加+1;諾從右到左索引從-1開始,依次加-1。
在Python 中訪問子序列/字符串,使用方括號[]
來截取指定的子序列/字符串。例如在列表中要元素2和3,則切片截取為LIST[1:3]
2.2 忽略最后一位元素
在Python中,進行切片操作會不包含最后一位元素,這一風格是與C語言等語言保存以索引位置從0開始的做法。
切片忽略最后一位元素會有以下好處:
當切片操作只給出最后一位時,可以直接明了看到截取的子序列的長度。例如LIST[:2]中包含兩個元素
根據(jù) Edsger W. Dijkstar 解釋,索引位置從0開始比從1開始優(yōu)勢,元素的序數(shù)(下標)等于序列中它之前的元素數(shù)。切片長度計算方式可以直接(stop-start)計算出
同時,指定任何一個索引位置x,可以對序列切割成不重疊的兩個子序列LIST[:x]和LIST[x:]。
>>> LIST = [1,2,3,4] >>> LIST[:2] # 直接可以知道截取子序列為2 [1, 2] >>> LIST[2:] # 將LIST在索引位置2處切片 [3, 4] >>>
3. 切片原理
切片操作是使用方括號 [] 進行運算的。其格式為 [start:stop:step]。對象在start和stop區(qū)間中取出間隔step的元素。step可以取負數(shù)。
>>> LIST[1:4:2] [2, 4] >>> LIST[-1:-4:-1] [4, 3, 2] >>> LIST[::-1] [4, 3, 2, 1] >>> LIST[::-2] [4, 2] >>>
start:stop:step 形式在方括號[]內(nèi),使用索引下標計算后,返回一個切片對象:slice(start,stop,step)
當序列進行seq[start:stop:step]分片計算時,Python會調(diào)用seq.getitem(slice(start,stop,step))方法以元組的形式接收[]方括號索引。
查看Python內(nèi)置 slice() 方法屬性,有三個start、stop和step數(shù)據(jù)屬性和indices方法
>>> slice <class 'slice'> >>> dir(slice) ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'indices', 'start', 'step', 'stop'] >>>
根據(jù)當序列調(diào)用slice方法后,會先執(zhí)行Seq.indices(len)
方法計算出序列Seq從開始start和結(jié)束stop位置,步數(shù)step。當超出邊界時,會截掉。
>>> slice(None,5,1).indices(2) #1 (0, 2, 1) >>> slice(-3,None,None).indices(2) #2 (0, 2, 1) >>>
#1 seq[:5:1] 等于 seq[0:2:1]
#2 seq[-3:] 等于 seq[0:2:1]
切片其實還可以支持使用逗號分開多個索引,例如第三庫Numpy庫就是使用這個特性。
4. 切片賦值
將序列進行切片操作后得到切片對象可以進行賦值,但是必須遵循以下條件:
切片做為對象,那么等號右邊必須是一個可迭代的對象
即使切片里只有一個值,也要轉(zhuǎn)換成可迭代的序列
否則的話,系統(tǒng)會拋出TypeError
>>> LIST = [1,2,3,4,5] >>> LIST[1:4] = 23 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only assign an iterable >>>
5. 切片計算
在Python中,切片對象可以進行 “+”或“*”運算,以達到拼接組合成新的切片對象。
通過 "+" 連接的是兩個同類型序列,兩個序列拼接后序列不會發(fā)生改變,Python內(nèi)部會重新創(chuàng)建新的序列
>>> LIST = [1,2,3,4] >>> LIST2 = [5,6,7] >>> LIST + LIST2 [1, 2, 3, 4, 5, 6, 7] >>> s1 = "Jue" >>> s2 = "Jin" >>> s1 + s2 'JueJin'
通過“Seq*n”,可以將原數(shù)據(jù)類型復制n份,然后再拼接起來組合新的序列
>>> LIST = [1,2,3,4] >>> LIST * 3 [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] >>> s1 = "Jue" >>> s1 * 3 'JueJueJue'
以上案例中,都是針對元素是不可變的數(shù)據(jù)類型進行復制操作的,那么元素是可變數(shù)據(jù)類型進行復制會發(fā)生什么樣呢?
例如我們要創(chuàng)建一個二維的列表,長度為3。可能快捷的寫法如下:
>>> LIST = [["_"]]*3 >>> LIST [['_'], ['_'], ['_']]
但是對坐標0,0進行賦值,發(fā)現(xiàn)3個元素都發(fā)生變化
>>> LIST[0][0] = 1 >>> LIST [[1], [1], [1]]
這個和我們實際想要的效果不一樣,我們需要得到是列表中每一個元素之間都是獨立的,那么我們寫法上要與上述有區(qū)別的
>>> LIST = [["_"] for i in range(3)] >>> LIST [['_'], ['_'], ['_']] >>> LIST[0][0] = 1 >>> LIST [[1], ['_'], ['_']] >>>
為什么兩種寫法差距這么大,原因在于第一種寫法雖然看上去和寫法二一樣,但是寫法一初始化時候,是得到元素都是引用,都指向同一個列表。當我們對其中一個元素進行賦值時,另外兩個也會跟著變化。
6. 總結(jié)
本期,對 Python 關(guān)于序列、字符串常用到的切片操作,進行深入學習。切片操作原理在于Python內(nèi)部會通過__getitem__()方法調(diào)用slice對象,然后slice對象通過indices(len)方法算出切片的長度。哪怕遇到缺失索引和負數(shù)索引,以及長度超過目標序列的切片都可以優(yōu)雅地進行處理。
原文鏈接:https://juejin.cn/post/7169494217490694151
相關(guān)推薦
- 2022-06-15 ASP.NET?Core?MVC中的控制器(Controller)介紹_基礎應用
- 2022-01-16 jQuery實現(xiàn)動畫效果和導航欄動態(tài)顯示
- 2022-03-16 Oracle數(shù)據(jù)庫分析函數(shù)用法_oracle
- 2024-03-17 基于linux使用Centos7實現(xiàn)Samba服務器安裝和配置(超詳細)
- 2022-12-11 Python?中用多種方式實現(xiàn)單例模式_python
- 2022-11-25 Go實現(xiàn)快速生成固定長度的隨機字符串_Golang
- 2022-04-15 Android一個類實現(xiàn)錄音與播放實例_Android
- 2022-08-01 flask-SQLALchemy連接數(shù)據(jù)庫的實現(xiàn)示例_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支