python自動化之路 day3 1

2021-07-24 07:13:26 字數 4678 閱讀 6845

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*xforxinrange(10))

>>>forning:

...print(n)

所以,我們建立乙個generator後,基本上永遠不會呼叫next(),而是通過for迴圈來迭代,不需要關心stopiteration錯誤

generator非常強大。如果推算的演算法比較複雜,用類似列表生成式的for迴圈無法實現的時候,還可以用函式來實現。

斐波拉契數列推算規則:

#!/usr/bin/env python

# _*_ 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關鍵字,那麼它不是乙個普通的函式,而是乙個生成器generator。每次呼叫next()時執行,

遇到yield語句返回,再執行時從上次的yield語句處繼續執行。同樣我們基本從來不用next()來獲取下乙個返回值,

而是直接使用for迴圈來迭代。

forn

inf:

print(n)

但是用for迴圈呼叫generator時,發現拿不到generator的return語句的返回值。如果想要拿到返回值,必須捕獲stopiteration錯誤,返回值包含在stopiterationvalue中:

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物件,但listdictstr雖然是iterable,卻不是iterator

你可能會問,為什麼listdictstr等資料型別不是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的語法:

try

:《語句》

#執行別的**

except

《名字》:

《語句》

#如果在try部份引發了'name'異常

except

《名字》,《資料》:

《語句》

#如果引發了'name'異常,獲得附加的資料

else

:《語句》

#如果沒有異常發生

try的工作原理是,當開始乙個try語句後,python就在當前程式的上下文中作標記,這樣當異常出現時就可以回到這裡,try子句先執行,接下來會發生什麼依賴於執行時是否出現異常。

未完待續。。。。

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...