1.迭代器和生成器
生成器
通過列表生成式,我們可以直接建立乙個列表,但是受記憶體限制,列表容器肯定是有限的,而建立乙個包含100萬個元素的列表,
不僅占用了很大的儲存空間,如果我們僅僅需要訪問前面幾個元素,那後面的絕大元素占用的空間就白白浪費了。
所以,如果列表元素可以按照某種演算法推算出來,那我們是否可以在迴圈的過程中不斷推斷算出後續元素呢?這樣就不必建立完整的list,從而節省大量的空間,
在python中,這種一遍迴圈一遍計算的機制,稱為生成器:generator
在python3.0中range函式是乙個迭代器。
>>> l = [x*x for x in range(10)]
>>> l
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x*x for x in range(10))
>>> g
at 0x024693a0>
>>>
建立l和g的區別僅僅在於最外層的 和 () ,l是乙個list,而g是乙個generator.
我們可以直接列印出list的每個元素,但我們怎麼列印出generator的每乙個元素呢?如果乙個個列印出來,可以通過next()函式獲得generator的下乙個返回值:
>>> g = (x*x for x in range(10))
>>> next(g)
0>>> next(g)
1>>> next(g)
4>>> next(g)
9>>> next(g)
16>>> next(g)
25>>> next(g)
36>>> next(g)
49>>> next(g)
64>>> next(g)
81>>> next(g)
traceback (most recent call last):
file "", line 1, in
stopiteration
generator儲存的是演算法,每次呼叫next(g),就計算出g下乙個元素的值,直到計算到最後乙個元素,沒有更多的元素時,丟擲stopiteration錯誤。
正確做法使用for迴圈,因為generator也是可迭代物件:
>>> g
=
(x
*
x
for
x
in
range
(
10
))
>>>
for
n
in
g:
...
print
(n)
所以,我們建立乙個generator後,基本上永遠不會呼叫next(),而是通過for迴圈來迭代,不需要關心stopiteration錯誤
generator非常強大。如果推算的演算法比較複雜,用類似列表生成式的for
迴圈無法實現的時候,還可以用函式來實現。
斐波拉契數列推算規則:
#!/usr/bin/env python如果函式定義中含有yield關鍵字,那麼它不是乙個普通的函式,而是乙個生成器generator。每次呼叫next()時執行,# _*_ coding:utf-8 _*_
deffibr(max):
n,a,b=0,0,1
whilen < max:
yieldb
a,b = b,a+b
n += 1
return"done"f = fibr(10)
print(f)
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
遇到yield語句返回,再執行時從上次的yield語句處繼續執行。同樣我們基本從來不用next()來獲取下乙個返回值,
而是直接使用for迴圈來迭代。
forninf:
print(n)
但是用for
迴圈呼叫generator時,發現拿不到generator的return
語句的返回值。如果想要拿到返回值,必須捕獲stopiteration
錯誤,返回值包含在stopiteration
的value
中:
while true:try:
x = next(f)
print(x)
exceptstopiteration
ase:
print("generator return value:",e.value)
break
迭代器我們已經知道,可以作用在for迴圈的資料型別有以下幾種:
一類是集合資料型別:list,dict,tuple,set,str
一類是generator,包括生成器和帶yield的generator function
這些直接作用於for迴圈的物件統稱為可迭代物件:iterable。
可以使用isinstance()判斷乙個物件是否是iterable物件
fromcollectionsimportiterable*可以被isinstance(,iterable)
isinstance({},iterable)
print(isinstance("abc",iterable))
next()
函式呼叫並不斷返回下乙個值的物件稱為迭代器:iterator
。
生成器都是iterator
物件,但list
、dict
、str
雖然是iterable
,卻不是iterator
。
你可能會問,為什麼list
、dict
、str
等資料型別不是iterator
?
這是因為python的iterator
物件表示的是乙個資料流,iterator物件可以被next()
函式呼叫並不斷返回下乙個資料,直到沒有資料時丟擲stopiteration
錯誤。可以把這個資料流看做是乙個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()
函式實現按需計算下乙個資料,所以iterator
的計算是惰性的,只有在需要返回下乙個資料時它才會計算。
iterator
甚至可以表示乙個無限大的資料流,例如全體自然數。而使用list是永遠不可能儲存全體自然數的。
it = iter([1,2,3,4,5,6])while true:
try:
x = next(it)
print(x)
exceptstopiteration:
break
異常處理
捕捉異常可以使用try/except語句。
try/except語句用來檢測try語句塊中的錯誤,從而讓except語句捕獲異常資訊並處理。
如果你不想在異常發生時結束你的程式,只需在try裡捕獲它。
語法:以下為簡單的try....except...else的語法:
trytry的工作原理是,當開始乙個try語句後,python就在當前程式的上下文中作標記,這樣當異常出現時就可以回到這裡,try子句先執行,接下來會發生什麼依賴於執行時是否出現異常。:《語句》
#執行別的**
except
《名字》:
《語句》
#如果在try部份引發了'name'異常
except
《名字》,《資料》:
《語句》
#如果引發了'name'異常,獲得附加的資料
else
:《語句》
#如果沒有異常發生
未完待續。。。。
Python學習之路 Day3
換課程期數了,不同老師教 開發人員在程式中自定義的一些符號和名稱。識別符號是自己定義的,如變數名 函式名等 組成 由26個英文本母大小寫,數字 0 9 符號 1.識別符號中可以包含字母 數字 但是不能使用數字開頭 例如 name1 name 1 name1 1name 不行 2.python中不能使...
PYTHON 自動化之路 (二)
模組的使用 import os 呼叫 os 模組 cmd s os.popen dir read 開啟路徑為結果儲存為cmd s print cmd s 列印結果 import sysprint sys.path 列印環境變數 建立乙個名為login.py的檔案儲存為相同目錄下 login.py a...
Python自動化運維之路Day4
abs 取絕對值 all 所有為真,則為真,否則為假 any 至少有乙個為真,就為真,否則為假 callable 判斷函式是否可以被呼叫,如果可以返回true,否則返回false bin 將十進位制數轉換為二進位制表示 hex 將十進位制的數值轉換為十六進製制 oct 將十進位制數值轉換為8進製 c...