python(六)切片,生成式,生成器,迭代

有了前面的基礎,其實掌握的比較紮實的話仍是可以作出一些簡單的東西的,至少解決一些個基本的數學題仍是問題不大,好比說實現一個斐波那契數列,楊輝三角什麼的。多數狀況下使用循環 for ... in  或者  while 再加上 if 等就可以實現些很複雜的程序了。python

接下來這部份內容的主要功能是爲了簡化循環而存在的,也秉持着python編程的一個原則:能一條代碼解決的事兒決不寫兩條。就這樣!編程

1,切片數據結構

切片,從字面上理解意思應該差很少可以到位。就是從一個大塊兒中切出來一片或者一起。這個大塊兒的東西,在程序中能夠是列表,元組,集合,字典,字符串等。編程語言

舉個例子,好比說從一個含有5個元素的列表中取出前三個元素,該怎麼實現?
函數

若是沒學切片以前,能夠用循環實現,就像這樣:編碼

可是若是使用python的切片操做,則很簡單,就像是這樣:spa

能夠看到,python的切片操做符使用的是「[start:end]」,start 和 end 均表示元素的索引,獲取到的元素在 [start, end) 之間,就是說包含 start 而不包含 end,若是你不指定 end 那麼默認就切到結尾。索引

經過切片操做對列表,元組等數據結構進行操做以後返回的數據類型和原數據類型相同。字符串

以上就是關於切片操做的基本介紹,固然,這也是它的所有。數學

那切片操做一般適用的場景就是,你但願能夠快速的從一個列表或者什麼中獲取其中的一部分,那麼用切片操做是最合適不過了!

固然了,切片操做還支持「倒着切」和對字符串進行切割。所謂的「倒着切」是由於,不論是列表仍是元組,它們最後一個元素的索引在python中「規定爲 -1」,那倒數第二個元素就是「-2」以此類推。

一個問題:切片能夠對集合或者字典進行切割嗎?解釋一下緣由。

2,生成式

生成式是另一種操做。切片的目的是從過一個已有的列表中切出一部分返回,而生成式的目的則是從無到有的構建一個列表。

一個案例:假如我準備構建一個含有10個元素的列表,能夠怎麼作?

這裏,能夠利用python的一個內置函數xrange來生產一些數字,而後利用循環填充到一個列表中。

那麼使用生成式應該怎麼實現呢?我仍是畫(截)個圖來看看:

效果同樣,可是代碼是否是少了不少。這就是python的編碼原則,儘量的少寫代碼!

同時呢,生成式還能夠像for同樣支持嵌套,固然了,不僅是一級嵌套,一樣也支持多級,不過一般狀況下最多也只能用到二級了吧。如下的例子,使用生成式來生成兩個字符串的全排列:

經過上面的兩個例子,想必你已經看到了生成式的運行過程了吧?

對,就是你所想的那樣,不要疑惑,記住它,在你之後的python路上這個會有很大的幫助!

注意:因爲生成式只能採用「[]」這種方式,因此只能生產「list」類型的數據結構,因此生成式,一般狀況下咱們稱之爲:列表生成式。

補充:其實還能夠生成集合,只須要把「[]」替換成「{}」

一個問題:上面的兩句話矛盾嗎?

3,生成器

若是你理解了生成式,那麼對於生成器來講你只須要懂一點,那就是在生成式知足不了你的時候, 你能夠考慮使用生成器。

因此生成器是生成式的增強版,注意:不是替代版!

一個案例:構建一個斐波那契數列數列的列表

方案一:採用循環的方式

因爲在python中支持同時給多個變量賦值,因此代碼能夠簡化成這樣:

這裏,簡化以後的代碼,最妙的一點我認爲在於:在其它編程語言中,若是要作到兩個變量的交換,那麼必定須要引入中間變量,可是在python中利用「賦值符號 =」支持多賦值的機制能夠很容易的避免這個問題。

上例中只是採用基本的python編程方法實現了咱們的要求,可是這裏能不能採用生成式來實現呢?

答案是能夠的!

方案二:採用生成器

有些生成式的邏輯太過於複雜,致使咱們沒辦法直接經過生成式來完成,這個時候能夠藉助於函數來完成複雜的邏輯,而後把函數轉換成生成器,這樣咱們就能夠「迭代」生成器來「模擬生成式」生成咱們須要的列表。

那麼在這裏,把普通函數轉換成生成器須要藉助一個關鍵字「yield」。

它的做用是中斷操做並返回,當下次再調用「next」方法的時候或者迭代的時候,從中斷出繼續執行,好比這樣:

那如今,對於生成器,是否是有了一個大概的影響呢?

其實還一個問題,我說生成器是做爲生成式的增強版,那麼是否是應該生成式具備的功能,生成器一樣應該具備呢?

就好比咱們說生成式的時候的第一個案例,生成一個含有10個元素的列表,若是用生成器應該怎麼實現?

能夠看到,生成器和生成式,構建的方法的區別在於一個才用的是「[]」而一個採用的是「()」

同時對於生成器,若是你想構建一個列表,那麼後期必需要經過「迭代」來實現,而生成式則能夠直接實現。

同時,因爲生成器的特殊性,致使若是你想訪問生成器中的各個元素,則須要調用它的「next」方法。

以上就是對於生成器所有介紹。

通過仔細思考,對比以後,你就會有下面的一些總結:

對於生成式,它很侷限,只可以幫助你快速的生成列表,而對於生成器,因爲後期元素的訪問必需要經過「迭代」,那麼「迭代」出來的元素能夠放到列表中,也能夠放到集合、元組、字典中,因此採用生成器對於最終構建出來的數據類型沒有限制。

那採用生成式仍是生成器,這個就須要根據狀況來自行決定了!

4,補充:迭代

什麼叫迭代?說白了就是作循環,並且仍是採用for ... in 這種循環結構。這就叫「迭代」!

上面這個,是咱們常常用,也是一種最簡單的迭代。

一樣,咱們也能夠迭代字典:

默認狀況下,迭代字典,迭代的是key,若是你想迭代value,你能夠這樣:採用 「itervalues」方法


固然,若是你想既迭代key也迭代value,那你能夠這樣:

而後,咱們來看看 「iteritems」這個方法獲得的數據類型:

看懂了這個類型,而後再看一個案例:

這樣,你對迭代是否是就已經很清楚了呢?^_^

有了迭代的基礎,再想一想,咱們的生成式和生成器,它們的內部不是也應用到了 for ... in 這種結構嗎?因而下面這樣子的代碼你還看不懂嗎?

O(∩_∩)O哈! 真是有趣,在python中,你能夠盡情的把你的代碼寫的「高大上」一些,並且這也正是python所推薦你這麼作的!

---------------------------------------------------華麗的分割線---------------------------------------------

切片,生成式,生成器,迭代,做爲前面對python擴展數據結構的操做的一些補充說明,在從此的python編程中應用會很是頻繁,因此必定要理解透徹,這樣才能編寫出「高大上」的代碼嘛 ^_^

相關文章
相關標籤/搜索