Python編程核心內容之二——切片、迭代和列表產生式,
Python版本:3.6.2 作業系統:Windows 作者:SmallWZQ
最近太忙啦。很多事情需要自己處理,感覺時間不夠用啊~~~~今後,部落格更新時間可能會慢下來,哈哈,正所謂“人不為己,天誅地滅”嘛。嘿嘿,沒這麼回事,說笑的……好像有扯遠了。OK,迴歸正題,下面將回到Python先~~~
Python編程中,你如果要編寫出很多有用的程式,必須掌握資料類型、語句和函數。對於Python編程,原則有二:一是代碼不是越多越好,而是越少越好;二是代碼不是越複雜越好,而是越簡單越好。你還想“一行代碼兩塊錢”。效率決定一切。
下面來個例子(不然,全是文字,會暈~~~)【實現1,3,5,7,9,……99的列表】:
1 #賺錢版代碼 2 >>>n = 1 3 >>>L = [] 4 >>>while n <= 99: 5 ... L.append(n) 6 ... n = n + 2 7 ... 8 >>>print(L) #好多money,但老闆不一定會給噢 9 #略縮版代碼10 >>>L= list(range(1,100,2))11 >>>print(L)12 #終極版代碼13 >>>[x for x in range(1,100,2)]
其實,上述代碼涉及到的代碼主要包括迴圈、range()、分區、列表產生式。通過例子,我們知道:Python提供了很多有用的進階特性,靈活運用這些特性,可以減少我們很多代碼量,提高效率。
切片
切片是Python編程的進階特性之一。切片可以訪問一定範圍內的元素,通過冒號(:)隔開兩個索引實現。
1 #切片的魔力2 >>>L = [1,2,3,4,5,6,7,8,9,10]3 >>>L[2:5]4 3,4,55 >>>L[0:1]6 1
切片操作的實現需要提供兩個索引作為邊界,第一個索引的元素是包含在切片內的,而第二個則不包含在切片內。
註:如果第一個索引是0,可以省略:
1 >>>L = [1,2,3,4,5,6,7,8,9,10]2 >>>L[0:3]3 1,2,34 >>>L[:3]5 1,2,3
既然Python支援L[-1]取倒數第一個元素,那麼它同樣支援倒數切片:
1 >>>L = [1,2,3,4,5,6,7,8,9,10]2 >>>L[-2:]3 9,104 >>>L[-2,-1]5 9
Python 3.x版本中,切片操作還支援步長:
1 >>>L = [1,2,3,4,5,6,7,8,9,10]2 >>>L[::1]3 [1,2,3,4,5,6,7,8,9,10]4 >>>L[0:10:2]5 [1,3,5,7,9]6 >>>L[1:10:5]7 [2,7]
tuple也是一種list,唯一區別是tuple不可變。因此,tuple也可以用切片操作,只是操作的結果仍是tuple:
1 >>> (0, 1, 2, 3, 4, 5)[:3]2 (0, 1, 2)
字串’xxx’也可以看成是一種list,每個元素就是一個字元。因此,字串也可以用切片操作,只是操作結果仍是字串:
1 >>> 'ABCDEFG'[:3]2 'ABC'3 >>> 'ABCDEFG'[::2]4 'ACEG'
Python沒有針對字串的截取函數,只需要切片一個操作就可以完成,非常簡單。
Python的切片非常靈活,一行代碼就可以實現很多行迴圈才能完成的操作。
迭代
Iteration是Python編程中最重要的進階特性。迭代(Iteration):給定一個list或tuple,通過for迴圈來遍曆這個list或tuple。故而,Python是通過for...in迴圈實現迭代的。
list這種資料類型雖然有下標,但很多其他資料類型是沒有下標的,但是,只要是可迭代對象,無論有無下標,都可以迭代,比如dict就可以迭代:
1 >>> d = {'A': 1, 'B': 2, 'C': 3}2 >>> for key in d:3 ... print(key)4 ...5 A6 B7 C8 >>>
因為dict的儲存不是按照list的方式順序排列,所以,迭代出的結果順序很可能不一樣。
預設情況下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同時迭代key和value,可以用for k, v in d.items()。
由於字串也是可迭代對象,因此,也可以作用於for迴圈:
1 >>> for ch in 'ABC':2 ... print(ch)3 ...4 A5 B6 C
因此,當我們使用for迴圈時,只要作用於一個可迭代對象,for迴圈就可以正常運行,而我們不太關心該對象究竟是list還是其他資料類型。
那麼,如何判斷一個對象是可迭代對象呢?方法是通過collections模組的Iterable類型判斷:
1 >>> from collections import Iterable2 >>> isinstance('abc', Iterable) # str是否可迭代3 True4 >>> isinstance([1,2,3], Iterable) # list是否可迭代5 True6 >>> isinstance(123, Iterable) # 整數是否可迭代7 False
在for迴圈裡,同時引用了兩個變數,在Python裡是很常見的,比如下面的代碼:
1 >>> for x, y in [(1, 1), (2, 4), (3, 9)]:2 ... print(x, y)3 ...4 1 15 2 46 3 9
任何可迭代對象都可以作用於for迴圈,包括我們自訂的資料類型,只要符合迭代條件,就可以使用for迴圈。
列表產生式
列表產生式作為Python編程的進階特性,可以簡化不少代碼量。列表產生式(List Comprehensions)是Python內建的非常簡單卻強大的可以用來建立list的產生式。
舉個例子,要產生list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11)):
1 >>> list(range(1, 11))2 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
但如果要產生[1x1, 2x2, 3x3, …, 10x10]怎麼做?方法一是迴圈:
1 >>> L = []2 >>> for x in range(1, 11):3 ... L.append(x * x)4 ...5 >>> L6 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
但是迴圈太繁瑣,而列表產生式則可以用一行語句代替迴圈產生上面的list:
1 >>> [x * x for x in range(1, 11)]2 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
寫列表產生式時,把要產生的元素x * x放到前面,後面跟for迴圈,就可以把list建立出來,for迴圈後面還可以加上if判斷,這樣我們就可以篩選出僅偶數的平方:
1 >>> [x * x for x in range(1, 11) if x % 2 == 0]2 [4, 16, 36, 64, 100]
列表產生式也可以使用兩個變數來產生list:
1 >>> d = {'x': 'A', 'y': 'B', 'z': 'C' }2 >>> [k + '=' + v for k, v in d.items()]3 ['y=B', 'x=A', 'z=C']
把一個list中所有的字串變成小寫:
1 >>> L = ['Hello', 'World', 'IBM', 'Apple']2 >>> [s.lower() for s in L]3 ['hello', 'world', 'ibm', 'apple']
列表產生式不是真正的語句,而是看起來像迴圈的運算式,這是將它歸為迴圈語句的原因。該功能很強大,但大多數情況下,直接使用迴圈和條件陳述式也能完成。然而,列表產生式的程式十分簡潔,更加易讀。
下面來個例子:
1 L1 = ['Hello', 'World', 18, 'Apple', None]2 L2= [s.lower() for s in L1 if isinstance(s,str)]