廖雪峰Python教程筆記(四)
- 6 高級特性
- 切片slice
- 迭代
- 列表生成式
- 生成器
- 迭代器
6 高級特性
在Python中,代碼不是越多越好,而是越少越好。代碼不是越復(fù)雜越好,而是越簡單越好。
基于這一思想,我們來介紹Python中非常有用的高級特性,1行代碼能實(shí)現(xiàn)的功能,決不寫5行代碼。請始終牢記,
代碼越少,開發(fā)效率越高
。
切片slice
經(jīng)常取指定索引范圍的操作,用循環(huán)十分繁瑣,因此,Python提供了切片(Slice)操作符
取前3個(gè)元素,用一行代碼就可以完成切片:
L[0:3]表示,從索引0開始取,直到索引3為止,但不包括索引3。即索引0,1,2,正好是3個(gè)元素。如果第一個(gè)索引是0,還可以省略: L[:3]
同樣支持倒數(shù)切片,試試:
迭代
如果給定一個(gè)list或tuple,我們可以通過for循環(huán)來遍歷這個(gè)list或tuple,這種遍歷我們稱為迭代(Iteration)。
在
Python中,迭代是通過for … in來完成
的,而很多語言比如C語言,迭代list是
通過下標(biāo)
完成的
Python的for循環(huán)不僅可以用在list或tuple上,還可以作用在其他可迭代對象上。
只要是可迭代對象,無論有無下標(biāo),都可以迭代,比如dict就可以迭代:
因?yàn)閐ict的存儲不是按照list的方式順序排列,所以,迭代出的結(jié)果順序很可能不一樣。
默認(rèn)情況下,dict迭代的是key。如果要迭代value,可以用for value in d.values(),
如果要同時(shí)迭代key和value,可以用for k, v in d.items()。
那么,如何判斷一個(gè)對象是可迭代對象呢?方法是通過collections模塊的Iterable類型判斷:
Python內(nèi)置的enumerate函數(shù)可以把一個(gè)list變成索引-元素對,這樣就可以在for循環(huán)中同時(shí)迭代索引和元素本身:
任何可迭代對象都可以作用于for循環(huán),包括我們自定義的數(shù)據(jù)類型,只要符合迭代條件,就可以使用for循環(huán)。
列表生成式
列表生成式即List Comprehensions,是Python內(nèi)置的非常簡單卻強(qiáng)大的
可以用來創(chuàng)建list的生成式。
要生成[1x1, 2x2, 3x3, …, 10x10]怎么做?
而列表生成式則可以用一行語句代替循環(huán)生成上面的list:
for循環(huán)后面還可以加上if判斷,這樣我們就可以篩選出僅偶數(shù)的平方:
還可以使用兩層循環(huán),可以生成全排列:
例如,列出當(dāng)前目錄下的所有文件和目錄名,可以通過一行代碼實(shí)現(xiàn)。
生成器
這種一邊循環(huán)一邊計(jì)算的機(jī)制,稱為生成器:generator。
要?jiǎng)?chuàng)建一個(gè)generator,有很多種方法。第一種方法很簡單,只要把一個(gè)列表生成式的[]改成(),就創(chuàng)建了一個(gè)generator:
創(chuàng)建L和g的區(qū)別僅在于最外層的[]和(),L是一個(gè)list,而g是一個(gè)generator。
我們可以直接打印出list的每一個(gè)元素,但我們怎么打印出generator的每一個(gè)元素呢?
如果要一個(gè)一個(gè)打印出來,可以
通過next()函數(shù)獲得generator的下一個(gè)返回值
:
正確的方法是使用for循環(huán),因?yàn)間enerator也是可迭代對象:
迭代器
可以直接作用于for循環(huán)的數(shù)據(jù)類型有以下幾種:
一類是集合數(shù)據(jù)類型,如list、tuple、dict、set、str等;
一類是generator,包括生成器和帶yield的generator function。
可以直接作用于for循環(huán)的對象統(tǒng)稱為可迭代對象:Iterable。
可以使用isinstance()判斷一個(gè)對象是否是Iterable對象:
而生成器不但可以作用于for循環(huán),還可以被next()函數(shù)不斷調(diào)用并返回下一個(gè)值,直到最后拋出StopIteration錯(cuò)誤表示無法繼續(xù)返回下一個(gè)值了。
可以被next()函數(shù)調(diào)用并不斷返回下一個(gè)值的對象稱為迭代器:Iterator 。
可以使用isinstance()判斷一個(gè)對象是否是Iterator對象:
生成器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator。
生成器都是Iterator對象,但list、dict、str雖然是Iterable,卻不是Iterator。
Python的Iterator對象表示的是一個(gè)數(shù)據(jù)流,Iterator對象可以被next()函數(shù)調(diào)用并不斷返回下一個(gè)數(shù)據(jù),直到?jīng)]有數(shù)據(jù)時(shí)拋出StopIteration錯(cuò)誤。可以把這個(gè)數(shù)據(jù)流看做是一個(gè)有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數(shù)實(shí)現(xiàn)按需計(jì)算下一個(gè)數(shù)據(jù),所以Iterator的計(jì)算是惰性的,只有在需要返回下一個(gè)數(shù)據(jù)時(shí)它才會計(jì)算。
Iterator甚至可以表示一個(gè)無限大的數(shù)據(jù)流,例如全體自然數(shù)。而使用list是永遠(yuǎn)不可能存儲全體自然數(shù)的。
小結(jié)
凡是可作用于for循環(huán)的對象都是Iterable類型;
凡是可作用于next()函數(shù)的對象都是Iterator類型,它們表示一個(gè)惰性計(jì)算的序列;
集合數(shù)據(jù)類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數(shù)獲得一個(gè)Iterator對象。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
