天天看點

Python進階特性(切片 疊代 清單生成式 生成器 疊代器)學習筆記

在Python中,代碼不是越多越好,而是越少越好。代碼不是越複雜越好,而是越簡單越好。

基于這一思想,Python中有非常有用的進階特性,1行代碼能實作的功能,決不寫5行代碼。請始終牢記,代碼越少,開發效率越高。

切片

(Slice)

  1. 切片操作符在python中的原型是 [start:stop:step] ,即:[開始索引:結束索引:步長值] ->

    開始索引:預設從0開始。序列從左向右方向中,第一個值的索引為0,最後一個為-1 ;

    結束索引:切片操作符将取到該索引為止,不包含該索引的值;

    步長值:預設是一個接着一個切取(值為1),如果為2,則表示進行隔一取一操作。步長值為正時表示從左向右取,如果為負,則表示從右向左取。步長值不能為0 。

Sequence[start:end:step] python的序列切片中,第一個:隔離了 起始索引 和 結束索引,第二個:隔離了 結束索引 和 步長

step為正,則從左到右切片,如果 start > end,則為空

step為負,則從右到左切片,如果 start < end,則為空

start 和 end 填空,前者表示最開始,後者表示最後一個, 同時為空的時候,表示取所有。至于方向,取決于 step

可以總結一句規律,step 為正表示從左到右切片,反之為右到左。

如:

L[a:b:c]

->表示,從索引a開始每隔c個間隔取,直到索引b為止,但不包括索引b。

  1. 隻寫[:]就可以原樣複制一個list。字元串也可以用切片操作,Python沒有針對字元串的截取函數,隻需要切片一個操作就可以完成。

疊代

可以通過for循環來周遊,這種周遊我們稱為疊代(Iteration)。任何可疊代對象都可以作用于for循環,包括我們自定義的資料類型,隻要符合疊代條件,就可以使用for循環。

  1. 在Python中,疊代是通過for … in來完成的,而很多語言比如C或者Java,疊代list是通過下标完成的。
  2. enumerate函數 :Python内置的enumerate函數可以把一個list變成索引-元素對,這樣就可以在for循環中同時疊代索引和元素本身。
#enumerate把list表索引
for i,value in enumerate(['A','B','C']):
    print(i,value)
           

輸出:

0 A

1 B

2 C

清單生成式

清單生成式(range())即List Comprehensions,是Python内置的非常簡單卻強大的可以用來建立list的生成式。

  1. list() 方法用于将元組轉換為清單。

    注:元組(tuple)與清單(list)是非常類似的,差別在于元組的元素值不能修改,元組是放在括号中,清單是放于方括号中。

  2. 運用清單生成式,可以快速生成list,可以通過一個list推導出另一個list,而代碼卻十分簡潔。
  3. for循環其實可以同時使用兩個甚至多個變量,比如dict的items()可以同時疊代key和value。
執行表達式 for 變量(k,v) in 集合(range())
           
  1. isinstance() 函數來判斷一個對象是否是一個已知的類型,類似 type()。

isinstance() 與 type() 差別:

type() 不會認為子類是一種父類類型,不考慮繼承關系。

isinstance() 會認為子類是一種父類類型,考慮繼承關系。

如果要判斷兩個類型是否相同推薦使用 isinstance()。

isinstance() 函數用法:

生成器

在Python中,這種一邊循環一邊計算的機制,稱為生成器:generator。

  1. 建立L和g的差別僅在于最外層的[]和(),L是一個list,而g是一個generator。定義generator的另一種方法。如果一個函數定義中包含yield關鍵字,那麼這個函數就不再是一個普通函數,而是一個generator。雖然執行流程仍按函數的流程執行,但每執行到一個 yield 語句就會中斷,并傳回一個疊代值,下次執行時從 yield 的下一個語句繼續執行。
  2. generator儲存的是算法,每次調用next(g),就計算出g的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,抛出StopIteration的錯誤。
  3. generator和函數的執行流程不一樣。函數是順序執行,遇到return語句或者最後一行函數語句就傳回。而變成generator的函數,在每次調用next()的時候執行,遇到yield語句傳回,再次執行時從上次傳回的yield語句處繼續執行。
  4. for循環調用generator時,發現拿不到generator的return語句的傳回值。如果想要拿到傳回值,必須捕獲StopIteration錯誤,傳回值包含在StopIteration的value中。關于如何捕獲錯誤,檢視後面的錯誤處理。
  5. 對于函數改成的generator來說,遇到return語句或者執行到函數體最後一行語句,就是結束generator的指令,for循環随之結束。

    注:請注意區分普通函數和generator函數,普通函數調用直接傳回結果;generator函數的“調用”實際傳回一個generator對象。

#斐波拉契數列(Fibonacci),除第一個和第二個數外,任意一個數都可由前兩個數相加得    到:1, 1, 2, 3, 5, 8, 13, 21, 34, ...
  代碼如下:
#使用生成器:generator
def fib(max):
    n,a,b = ,,
    while n < max:
        yield (b)
        a,b = b,a+b #把a指派給n會導緻n的個數随fib數增長
        n = n+
        return 'done'
for n in fib(): #循環疊代
    print(n)
           

擷取return的傳回值’done’

while True:
    try:
        x = next(g)
        print('g:', x)
    except StopIteration as e:
        print('Generator return value:', e.value)
        break
           

疊代

可以被next()函數調用并不斷傳回下一個值的對象稱為疊代器:Iterator。

  1. 可以直接作用于for循環的資料類型有以下幾種:

    一類是集合資料類型,如list、tuple、dict、set、str等;一類是generator,包括生成器和帶yield的generator function。

這些可以直接作用于for循環的對象統稱為可疊代對象:Iterable。可以使用isinstance()判斷一個對象是否是Iterable對象。

  1. iter()函數:生成器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator。把list、dict、str等Iterable變成Iterator可以使用iter()函數.

16.Python的Iterator對象表示的是一個資料流,Iterator的計算是惰性的,隻有在需要傳回下一個資料時它才會計算。

總結:

凡是可作用于for循環的對象都是Iterable類型;

凡是可作用于next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;

集合資料類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象。

學習網站: www.liaoxuefeng.com