成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python 的切片為什么不會(huì)索引越界?

開發(fā) 后端
切片主要用于序列對(duì)象中,按照索引區(qū)間截取出一段索引的內(nèi)容。那么,Python 的切片語法為什么不會(huì)出現(xiàn)索引越界呢?

切片(slice)是 Python 中一種很有特色的特性,在正式開始之前,我們先來復(fù)習(xí)一下關(guān)于切片的知識(shí)吧。

切片主要用于序列對(duì)象中,按照索引區(qū)間截取出一段索引的內(nèi)容。

[[441313]]

切片的書寫形式:[i : i+n : m] ;其中,i 是切片的起始索引值,為列表首位時(shí)可省略;i+n 是切片的結(jié)束位置,為列表末位時(shí)可省略;m 可以不提供,默認(rèn)值是 1,不允許為 0,當(dāng) m 為負(fù)數(shù)時(shí),列表翻轉(zhuǎn)。

切片的基本含義是:從序列的第 i 位索引起,向右取到后 n 位元素為止,按 m 間隔過濾 。

下面是一些很有代表性的例子,基本涵蓋了切片語法的使用要點(diǎn):

  1. # @Python貓 
  2. li = [1, 4, 5, 6, 7, 9, 11, 14, 16] 
  3.  
  4. # 以下寫法都可以表示整個(gè)列表,其中 X >= len(li) 
  5. li[0:X] == li[0:] == li[:X] == li[:] == li[::] == li[-X:X] == li[-X:] 
  6.  
  7. li[1:5] == [4,5,6,7] # 從1起,取5-1位元素 
  8. li[1:5:2] == [4,6] # 從1起,取5-1位元素,按2間隔過濾 
  9. li[-1:] == [16] # 取倒數(shù)第一個(gè)元素 
  10. li[-4:-2] == [9, 11] # 從倒數(shù)第四起,取-2-(-4)=2位元素 
  11. li[:-2] == li[-len(li):-2] == [1,4,5,6,7,9,11] # 從頭開始,取-2-(-len(li))=7位元素 
  12.  
  13. # 步長(zhǎng)為負(fù)數(shù)時(shí),列表先翻轉(zhuǎn),再截取 
  14. li[::-1] == [16,14,11,9,7,6,5,4,1] # 翻轉(zhuǎn)整個(gè)列表 
  15. li[::-2] == [16,11,7,5,1] # 翻轉(zhuǎn)整個(gè)列表,再按2間隔過濾 
  16. li[:-5:-1] == [16,14,11,9] # 翻轉(zhuǎn)整個(gè)列表,取-5-(-len(li))=4位元素 
  17. li[:-5:-3] == [16,9] # 翻轉(zhuǎn)整個(gè)列表,取-5-(-len(li))=4位元素,再按3間隔過濾 
  18.  
  19. # 切片的步長(zhǎng)不可以為0 
  20. li[::0]  # 報(bào)錯(cuò)(ValueError: slice step cannot be zero) 

像 C/C++、Java 和 JavaScript 等語言,雖然也支持某些“切片”功能,例如截取數(shù)組或字符串的片段,但是,它們并沒有一種在語法層面上的通用性支持。

根據(jù)維基百科資料,F(xiàn)ortran 是最早支持切片語法的語言(1966),而 Python 則是最具代表性的語言之一。

主要編程語言對(duì)切片的支持

另外,像 Perl、Ruby、Go 和 Rust 等語言,雖然也有切片,但都不及 Python 那樣靈活和自由(因?yàn)樗С? step、負(fù)數(shù)索引、缺省索引)。

編程語言中切片語法的形式

切片的基本用法就能夠滿足大部分的需求,但是,Python 切片還有一些進(jìn)階的用法,例如:切片占位符用法(可實(shí)現(xiàn)列表的賦值、刪除與拼接操作)、自定義對(duì)象實(shí)現(xiàn)切片功能、迭代器切片(itertools.islice())、文件對(duì)象切片等等。關(guān)聯(lián)閱讀:Python進(jìn)階:全面解讀高級(jí)特性之切片!

關(guān)于切片的介紹與溫習(xí),就到這里了。

下面進(jìn)入文章標(biāo)題的問題:Python 的切片語法為什么不會(huì)出現(xiàn)索引越界呢?

當(dāng)我們根據(jù)單個(gè)索引進(jìn)行取值時(shí),如果索引越界,就會(huì)得到報(bào)錯(cuò):“IndexError: list index out of range”。

  1. >>> li = [1, 2] 
  2. >>> li[5] 
  3. Traceback (most recent call last): 
  4.   File "<stdin>", line 1, in <module> 
  5. IndexError: list index out of range 

對(duì)于一個(gè)非空的序列對(duì)象,假設(shè)其長(zhǎng)度為 length,則它有效的索引值是從 0 到(length - 1)。如果把負(fù)數(shù)索引也考慮進(jìn)去,則單個(gè)索引值的有效區(qū)間是 [-length, length - 1] 閉區(qū)間。

但是,當(dāng) Python 切片中的索引超出這個(gè)范圍時(shí),程序并不會(huì)報(bào)錯(cuò)。

  1. >>> li = [1, 2] 
  2. >>> li[1:5]  # 右索引超出 
  3. [2] 
  4. >>> li[5:6]  # 左右索引都超出 
  5. [] 

其實(shí),對(duì)于這種現(xiàn)象,官方文檔中有所介紹:

The slice of s from i to j is defined as the sequence of items with index k such that i <= k < j. If ior j is greater than len(s), use len(s). If i is omitted or None, use 0. If j is omitted or None, use len(s). If i is greater than or equal to j, the slice is empty.

也就是說:

  • 當(dāng)左或右索引值大于序列的長(zhǎng)度值時(shí),就用長(zhǎng)度值作為該索引值;
  • 當(dāng)左索引值缺省或者為 None 時(shí),就用 0 作為左索引值;
  • 當(dāng)右索引值缺省或者為 None 時(shí),就用序列長(zhǎng)度值作為右索引值;
  • 當(dāng)左索引值大于等于右索引值時(shí),切片結(jié)果為空對(duì)象。

對(duì)照上面的例子,可以得到:

  1. >>> li = [1, 2] 
  2. >>> li[1:5]  # 等價(jià)于 li[1:2] 
  3. [2] 
  4. >>> li[5:6]  # 等價(jià)于 li[2:2] 
  5. [] 

歸結(jié)起來一句話:Python 解釋器把可能導(dǎo)致索引越界的操作給屏蔽了,你的寫法可以很自由,但是最終的結(jié)果會(huì)被死死限制在合法的索引區(qū)間內(nèi)。

對(duì)于這個(gè)現(xiàn)象,我其實(shí)是有點(diǎn)疑惑的,為什么 Python 不直接報(bào)索引越界呢,為什么要修正切片的邊界值,為什么一定要返回一個(gè)值呢,即便這個(gè)值可能是個(gè)空序列?

當(dāng)我們使用“li[5:6]”時(shí),至少在字面意義上想表達(dá)的是“取出索引從 5 到 6 所對(duì)應(yīng)的值”,就像是在說“取出書架上從左往右數(shù)的第 6 和 7 本書”。

如果程序是如實(shí)地遵照我們的指令的話,它就應(yīng)該報(bào)錯(cuò),就應(yīng)該說:對(duì)不起,書架上的書不夠數(shù)。

實(shí)話說,我并沒有查到這方面的解釋,這篇文章也不是要給大家科普 Python 在設(shè)計(jì)上有什么獨(dú)到的見解。恰恰相反,這篇文章的主要目的之一是希望得到大家的回復(fù)解答。

在 Go 語言中,遇到同樣的場(chǎng)景時(shí),它的做法是報(bào)錯(cuò)“runtime error: slice bounds out of range”。

在 Rust 語言中,遇到同樣的場(chǎng)景時(shí),它的做法是報(bào)錯(cuò)“byte index 5 is out of bounds of ......”。

在其它支持切片語法的語言中,也許還有跟 Python 一樣的設(shè)計(jì)。但是,我還不知道有沒有(學(xué)識(shí)淺薄)……

最后,繼續(xù)回到標(biāo)題中的問題“Python 的切片為什么不會(huì)索引越界”。我其實(shí)想問的問題有兩個(gè):

當(dāng)切片語法中的索引超出邊界時(shí),為什么 Python 還能返回結(jié)果,返回結(jié)果的計(jì)算原理是什么?

為什么 Python 的切片語法要允許索引超出邊界呢,為什么不設(shè)計(jì)成拋出索引錯(cuò)誤?

對(duì)于第一個(gè)問題的回答,官方文檔已經(jīng)寫得很明白了。

對(duì)于第二個(gè)問題,本文暫時(shí)沒有答案。

也許我很快就能找到答案,但是,也可能需要很久。不管如何,本文先到此為止了。

 

責(zé)任編輯:趙寧寧 來源: Python貓
相關(guān)推薦

2012-11-13 10:27:45

PythonGo編程語言

2015-07-22 16:46:13

Windows 11理由

2013-08-23 14:22:45

SA系統(tǒng)管理員運(yùn)維

2020-09-04 15:34:07

C編程語言開發(fā)

2020-01-15 08:42:16

TCP三次握手弱網(wǎng)絡(luò)

2021-02-16 00:33:56

Python語言工具

2012-06-27 10:26:19

Surface

2020-02-11 15:30:51

Redis快照數(shù)據(jù)庫

2014-09-22 09:27:57

Python

2018-06-20 00:52:05

SD-WANMPLSWAN

2021-02-03 08:52:52

Mysql索引數(shù)據(jù)庫

2021-07-29 10:08:15

NumPy索引切片

2021-12-13 01:40:29

ElasticSear倒排索引

2014-12-26 09:56:50

編程語言

2009-07-27 16:07:27

MySQLOracle

2023-12-27 08:12:04

切片Go語言

2017-04-20 09:01:17

5G網(wǎng)絡(luò)切片

2023-09-22 10:05:32

2022-10-25 22:09:58

Designreactantd

2015-02-27 10:09:13

云計(jì)算
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 日本精品裸体写真集在线观看 | 成人精品一区亚洲午夜久久久 | 免费观看一级毛片视频 | 四虎影 | 久久久91精品国产一区二区三区 | 一级无毛片 | 久久久亚洲| 免费看黄色国产 | 久久久久国产一区二区三区 | 91久久久www播放日本观看 | 免费网站在线 | 国产精品久久久久久妇女6080 | 午夜免费网站 | 密色视频| 日本特黄a级高清免费大片 国产精品久久性 | 色啪网| av先锋资源 | 国产视频观看 | 亚洲免费高清 | 九九热在线观看 | 日日夜夜天天干 | 二区av | 亚洲精品久久久 | av网站在线播放 | 国产精品视频一区二区三区 | 一级久久久久久 | 国产精品一区二区久久久久 | 黄色一级视频 | 国产精品视频一区二区三区, | 99精品电影 | 国产欧美日韩在线播放 | 欧美精品二区三区 | 免费人成激情视频在线观看冫 | 正在播放国产精品 | www.99热| 中文字幕一区二区三区精彩视频 | 欧美激情视频一区二区三区在线播放 | 中文字幕视频在线观看 | 精品久久99 | 日韩欧美中文在线 | 亚洲一区二区三区在线视频 |