本文為廖雪峰Python教程的學習筆記
具體內容,可參考如下連結:
http://www.liaoxuefeng.com/ 1. 切片(Slice)
從list, tuple或string中截取一段出來。
[i : j : k]表示在列表中i <= index < j的開區間中以步長為k取出部分元素,步長預設為1,如果k < 0,表示逆序切片。
L = list(range(100))#取出L[0], L[1], L[2]L[0:3]
2. 迭代
不使用下標,遍曆任何可迭代對象。如list, tuple, dict, string.
#迭代dict類型#預設對key迭代for key in d: print(key)#迭代valuefor value in d.values(): print(value)#同時迭代key, valuefor key, value in d.items(): print(key, value)
判斷一個對象是否可迭代,通過collections模組的Iterable類型判斷。
from collections import Iterable#判斷對象是否可迭代,返回True或Falseisinstance(obj, Iterable)
如果使用下標迴圈,函數enumerate()可以把list變為索引-元素對,可以在for迴圈中迭代索引和元素。
L = 'abcdefg'for i, value in enumerate(L): print(i, value)
3. 列表產生式(List Comprehensions)
用來建立list的產生式。
元素在前,用for語句產生。可以加上if判斷,還可以雙層迴圈。
#for語句,產生結果[1, 4, 9, 16, 25, 36, 49, 64, 81, 100][x * x for x in range(1, 11)]#if語句,僅保留偶數的平方,產生結果[4, 16, 36, 64, 100][x * x for x in range(1, 11) if x % 2 == 0]#雙層迴圈,產生全排列,產生結果['aX', 'aY', 'aZ', 'bX', 'bY', 'bZ', 'cX', 'cY', 'cZ'][m + n for m in 'abc' for n in 'XYZ']#三層迴圈,全排列,結果['aX1', 'aX2', 'aY1', 'aY2', 'bX1', 'bX2', 'bY1', 'bY2'][m + n + q for m in 'ab' for n in 'XY' for q in '12']
列出目前的目錄下的所有檔案和目錄名。
os.listdir()可以列出檔案和目錄。
#匯入os模組import osdirs = [dir for dir in os.listdir('.')]print(dirs)
把list中所有字串變為小寫。
L = ['A', 'b', 'C', 'D']print([e.lower() for e in L])print(L)
輸出結果為:
['a', 'b', 'c', 'd']['A', 'b', 'C', 'D']
列表產生式新產生一個列表,並不改變原列表的值。
如果list中既包含字串,又包含整數,由於非字串類型沒有lower()方法,所以列表產生式會報錯,可以在if語句中用isinstance()函數判斷元素是否為字元類型,再轉為小寫。
L = ['Hello', 'World', 18, 'Apple', None][s.lower() for s in L if isinstance(s, str)]#結果為['hello', 'world', 'apple']
4. 產生器(generator)
產生器不必建立完整list,可以邊迴圈邊計算出要使用的list元素,節省了大量的空間。
把列表產生式的[]改為(),就可以建立一個generator。
可以直接列印出list的每個元素,generator的通過next()獲得下一個傳回值。
generator儲存的是演算法,每次調用next(g),就計算出g的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,拋出StopIteration的錯誤。
generator是可迭代對象,可以使用for迴圈列印,使用for迴圈迭代,不用擔心沒有元素可列印時出現StopIteration錯誤。。
l = [2 * x for x in range(1, 6)]g = (2 * x for x in range(1, 6))print(l)#直接列印generator會報錯print(g)print(next(g))# print(next(g))print('for')#for迴圈接著當前已經列印過的元素列印for n in g: print(n)
結果如下:
[2, 4, 6, 8, 10]<generator object <genexpr> at 0x01D81C10>2for46810
如果一個函數定義中包含yield關鍵字,那麼這個函數就不再是一個普通函數,而是一個generator,yield語句代替print語句。
例如,列印斐波那契數列的前n個數
#列印斐波那契數列的前n個數def fib(max): n, a, b, = 0, 0, 1 while n < max: yield(b) a, b = b, a+b n = n + 1 return 'done'f = fib(5)#可以使用for語句列印f中的所有元素# for num in f:# print(num)print(next(f))print(next(f))print(next(f))
每次調用next()函數,相當於函數fib()執行到yield語句,並列印結果,調用下一個next時,從上次的yield處繼續執行,遇到return語句或執行到最後一行語句時,結束generator。結果為:
112
但是用for迴圈調用generator時,拿不到generator的return語句的傳回值。如果想要拿到傳回值,必須捕獲StopIteration錯誤,傳回值包含在StopIteration的value中.
再例如,列印楊輝三角的前n行:
def triangles(): prel = [] while True: newl = [] a = 0 for b in prel: newl.append(a+b) a = b newl.append(1) prel = newl yield(newl)#列印楊輝三角的前10行n = 0for t in triangles(): print(t) n = n + 1 if n == 10: break
結果如下:
[1][1, 1][1, 2, 1][1, 3, 3, 1][1, 4, 6, 4, 1][1, 5, 10, 10, 5, 1][1, 6, 15, 20, 15, 6, 1][1, 7, 21, 35, 35, 21, 7, 1][1, 8, 28, 56, 70, 56, 28, 8, 1][1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
5. 迭代器
可以直接作用於for迴圈的對象統稱為可迭代對象:Iterable。
可迭代的資料類型包括集合資料類型(如list、tuple、dict、set、str等)和產生器。
凡是可作用於for迴圈的對象都是Iterable類型;
凡是可作用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列,只有在需要返回下一個資料是才會計算。
Iterator可以表示無限大的資料流,但list不可以。
集合資料類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象。
from collections import Iterablefrom collections import IteratorL = [1, 2, 3]G = (x for x in range(1, 4))#list是可迭代對象但不是迭代器print(isinstance(L, Iterable)) #Trueprint(isinstance(L, Iterator)) #False #產生器既是可迭代對象又是迭代器print(isinstance(G, Iterable)) #Trueprint(isinstance(G, Iterator)) #True#iter()函數將可迭代對象轉換為迭代器L1 = iter(L)print(isinstance(L, Iterator)) #Falseprint(isinstance(L1, Iterator)) #True