- 列表生成式
- 函數(shù)的參數(shù)類型
- lambda函數(shù)
- map, reduce, filter, sorted函數(shù)
- eval, exec, join, zip函數(shù)
- itertools中的函數(shù)
- copy與deepcopy函數(shù)
- 模塊
- os团滥、sys模塊
- 迭代器
- 生成器
- 迭代器
參考網(wǎng)站:
- Python3教程: https://www.python-course.eu/python3_course.php
- Python之函數(shù)參數(shù)的使用:https://blog.csdn.net/jclian91/article/details/78309522
- 廖雪峰Python教程: https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
- Python之淺談exec函數(shù): https://blog.csdn.net/jclian91/article/details/80076512
- Python官網(wǎng)的itertools說明: https://docs.python.org/3.6/library/itertools.html
- Python-copy()與deepcopy()區(qū)別: https://blog.csdn.net/qq_32907349/article/details/52190796
- copy模塊官網(wǎng):https://docs.python.org/3.5/library/copy.html
列表生成式
列表生成式即List Comprehensions,是Python內(nèi)置的非常簡單卻強大的可以用來創(chuàng)建list的生成式窥妇。一般是利用原有的數(shù)據(jù)結構來生成新的列表述雾。
# 利用range()生成[1,2,...,9,10]
list(range(1,11))
# 生成[1x1, 2x2, 3x3, ..., 10x10]
[x * x for x in range(1, 11)]
# 可以通過占位符_代表列表中的元素
[_*_ for _ in range(1,11)]
# 篩選出僅偶數(shù)的平方, 在for循環(huán)后加上if判斷語句
[x * x for x in range(1, 11) if x % 2 == 0]
# 利用占位符簡化
[_*_ for _ in range(1, 11) if not _%2]
# 兩層循環(huán)玷坠,三層循環(huán),....
[m + n for m in 'ABC' for n in 'XYZ']
[x+y+z for x in 'ab' for y in 'cd' for z in 'ef']
# 遍歷字典,生成列表
d = {'x': 'A', 'y': 'B', 'z': 'C' }
[k + '=' + v for k, v in d.items()]
函數(shù)的參數(shù)類型
在Python中定義函數(shù)弊攘,其參數(shù)類型有:
- 位置參數(shù)
- 默認參數(shù)
- 可變參數(shù)
- 關鍵字參數(shù)
這4種參數(shù)都可以一起使用,或者只用其中某些姑曙,但是請注意襟交,參數(shù)定義的順序必須是:位置參數(shù)、默認參數(shù)伤靠、可變參數(shù)和關鍵字參數(shù)捣域。
可變參數(shù)以*開頭,允許傳入0個或任意個參數(shù)宴合,這些可變參數(shù)在函數(shù)調(diào)用時自動組裝為一個tuple焕梅。關鍵字參數(shù)以**開頭,允許傳入0個或任意個參數(shù)卦洽,這些可變參數(shù)在函數(shù)調(diào)用時自動組裝為一個dict贞言。若默認參數(shù)與可變參數(shù)放在一起,則接受完默認參數(shù)后阀蒂,其后參數(shù)為可變參數(shù)。
位置參數(shù)
位置參數(shù)指定名稱的必須放在未指定名稱的后面
def person(name,age,city):
s = "info: name=%s, age=%s, city=%s"%(name,age,city)
return s
print(person('Jack', 25, 'NY'))
print(person(name='Jack', age=25, city='NY'))
print(person('Jack', 25, city='NY'))
# 下面的參數(shù)使用有誤争便,位置參數(shù)指定名稱的必須放在未指定名稱的后面
print(person(name='Jack', 25, 'NY'))
默認參數(shù)
默認參數(shù)必須放在非默認參數(shù)的后面,可以該表默認參數(shù)的值
def person(name, city, age=18):
s = "info: name=%s, age=%s, city=%s"%(name,age,city)
return s
print(person('Jack', 'NY'))
print(person('Jack', 'NY', 20))
可變參數(shù)
可變參數(shù)以*開頭奏纪,允許傳入0個或任意個參數(shù)兔簇,這些可變參數(shù)在函數(shù)調(diào)用時自動組裝為一個tuple经柴。函數(shù)參數(shù)的長度是可以變化的牛哺, 例如內(nèi)置的sum, min, max等
def var_sum(*args):
sum = 0
for i in args:
sum += i
return sum
print(var_sum(1,2,3))
print(var_sum(1,2,3,4))
# 利用*號來分解參數(shù)
print(var_sum(*[1,2,3,4,5]))
若位置參數(shù)或默認參數(shù)與可變參數(shù)放在一起痒玩,則接受完位置參數(shù)或默認參數(shù)后便瑟,其后參數(shù)為可變參數(shù)颁督。
def var_sum(a, *args):
sum = 0
for i in args:
sum += i
print('a is %s, sum is %s'%(a,sum))
var_sum(1,2)
var_sum(1,2,3)
關鍵字參數(shù)
關鍵字參數(shù)以**開頭,允許傳入0個或任意個參數(shù),這些可變參數(shù)在函數(shù)調(diào)用時自動組裝為一個dict。
def test_args(**kwargs):
print('-'*20)
for key in kwargs:
print('key:', key, ',value:', kwargs[key])
print()
test_args(a=1,b=2)
test_args(a=1,b=2,c=3)
lambda函數(shù)
lambda函數(shù)即為匿名函數(shù),用關鍵字lambda表示,冒號(:)前面的為參數(shù),后面為返回值,不用寫return.
如:
lambda x: x*x
匿名函數(shù)有個限制,就是只能有一個表達式,一般一行代碼闸餐,不用寫return拂铡,返回值就是該表達式的結果失球。
用匿名函數(shù)有個好處,因為函數(shù)沒有名字实苞,不必擔心函數(shù)名沖突硬梁。此外阶剑,匿名函數(shù)也是一個函數(shù)對象磨确,也可以把匿名函數(shù)賦值給一個變量乏奥,再利用變量來調(diào)用該函數(shù),即函數(shù)也是變量媳瞪,此為函數(shù)式編程(functional programming)思想骗炉。
f = lambda x: x*x
f(5)
map, reduce, filter, sorted函數(shù)
map函數(shù)
map()函數(shù)接收兩個參數(shù),一個是函數(shù)蛇受,一個是Iterable句葵,map將傳入的函數(shù)依次作用到序列的每個元素,并把結果作為新的Iterator返回龙巨。
可以直接作用于for循環(huán)的對象統(tǒng)稱為可迭代對象:Iterable.
舉例說明,比如我們有一個函數(shù)f(x)=x^2熊响,要把這個函數(shù)作用在一個list [1, 2, 3, 4, 5, 6, 7, 8, 9]上旨别,就可以用map()實現(xiàn)如下:
# map函數(shù): 一一映射
def f(x):
return x * x
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(r)
# 利用lambda簡化上述代碼
list(map(lambda x: x*x, range(1, 11)))
再例如: 把list所有數(shù)字轉為字符串:
list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
reduce函數(shù)
reduce把一個函數(shù)作用在一個序列[x1, x2, x3, ...]上,這個函數(shù)必須接收兩個參數(shù)汗茄,一個是函數(shù)秸弛,一個是Iterable. reduce把結果繼續(xù)和序列的下一個元素做累積計算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比方說對一個序列求和洪碳,就可以用reduce實現(xiàn):
# 導入reduce, 這很重要
from functools import reduce
def add(x, y):
return x + y
reduce(add, [1, 3, 5, 7, 9])
# 利用lambda函數(shù)簡化
reduce(lambda x,y: x+y, range(1,10,2))
作業(yè): 利用reduce將序列[1, 3, 5, 7, 9]轉化為整數(shù)13579.
map, reduce的一個復雜例子:
將字符串列表['1', '3', '5', '7', '9']轉化為整數(shù)13579
from functools import reduce
a = ['1', '3', '5', '7', '9']
t = reduce(lambda x,y: 10*x+y, map(int, a))
print(t)
filter函數(shù)
Python內(nèi)建的filter()函數(shù)用于過濾序列递览。
和map()類似,filter()也接收一個函數(shù)和一個序列瞳腌。和map()不同的是绞铃,filter()把傳入的函數(shù)依次作用于每個元素,然后根據(jù)返回值是True還是False決定保留還是丟棄該元素嫂侍。
例如儿捧,在一個list中荚坞,刪掉偶數(shù),只保留奇數(shù)菲盾,可以這么寫:
list(filter(lambda x: x%2 == 1, [1, 2, 4, 5, 6, 9, 10, 15]))
sorted函數(shù)
Python內(nèi)置的sorted()函數(shù)就可以對list進行排序颓影。
sorted([36, 5, -12, 9, -21])
此外,sorted()函數(shù)還可以接收一個key函數(shù)來實現(xiàn)自定義的排序懒鉴,例如按絕對值大小排序:
sorted([36, 5, -12, 9, -21], key=abs)
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
高階函數(shù)诡挂,就是讓函數(shù)的參數(shù)能夠接收別的函數(shù)。map, reduce, filter, sorted都是高階函數(shù)临谱。
join, zip, eval, exec函數(shù)
join函數(shù)
Python中的join函數(shù)有兩個璃俗,分別為: join()和os.path.join(),具體作用如下:
- join(): 連接字符串數(shù)組吴裤。將字符串旧找、元組、列表中的元素以指定的字符(分隔符)連接生成一個新的字符串
- os.path.join(): 將多個路徑組合后返回
字符串中的join()函數(shù)的使用方法:
'sep'.join(seq)
sep:分隔符麦牺∨ブ耄可以為空。 seq:要連接的元素序列剖膳。 返回一個新的字符串魏颓。
seq = ['hello','good','boy','Dido']
print(' '.join(seq))
print('*'.join(seq))
zip函數(shù)
zip() 函數(shù)用于將可迭代的對象作為參數(shù),將對象中對應的元素打包成一個個元組吱晒,然后返回由這些元組組成的列表甸饱。
如果各個迭代器的元素個數(shù)不一致,則返回列表長度與最短的對象相同仑濒,利用 * 號操作符叹话,可以將元組解壓為列表。
# basic use of zip
x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)
print(list(zipped))
# zip for loops
for i,j in zip(x,y):
print(i, "->", j)
# unzip the list
a = [(1,2,3), (3,4,5)]
x2, y2, z2 = zip(*a)
print(x2)
print(y2)
print(z2)
# transpose a matrix
mtx = [(1, 2),
(3, 4),
(5, 6)]
print(list(zip(*mtx)))
# clustering a data series into n-length groups idiom
seq = range(1, 10)
print(list(zip(*[iter(seq)]*3)))
# dict and zip
keys = ['spam', 'eggs']
vals = [42, 1729]
d = dict(zip(keys, vals))
print(d)
eval函數(shù)
eval函數(shù)用來計算字符串表達式的值
t = eval("23")
print(t)
print(type(t))
print(eval("(1+2)*(3+4)"))
exec函數(shù)
exec()是Python的內(nèi)置函數(shù)墩瞳,不同于eval()函數(shù)只能執(zhí)行計算數(shù)學表達式的結果的功能驼壶,exec()能夠動態(tài)地執(zhí)行復雜的Python代碼,能夠十分強大喉酌。
簡單例子:
# 執(zhí)行簡單的Python語句
i = 12
j = 13
exec("answer=i*j")
print("Answer is %s"%answer)
# 執(zhí)行復雜的Python語句
func = "def fact(n):\n\treturn 1 if n==1 else n*fact(n-1)"
exec(func)
a = fact(5)
print(a)
exec函數(shù)還可以執(zhí)行儲存在其他文件中的Python代碼热凹,例如位于E盤的eg.txt,如下:
def fact(n):
if n==1:
return 1
else:
return n*fact(n-1)
t = fact(6)
print(t)
利用exec函數(shù)執(zhí)行eg.txt中的代碼:
with open('E://eg.txt', 'r') as f:
s = f.read()
exec(s)
還可以在exec()函數(shù)中加入?yún)?shù),參數(shù)的傳遞可以寫成字典(dict)形式。
x = 10
expr = """
z = 30
sum = x + y + z
print(sum)
"""
def func():
y = 20
exec(expr)
exec(expr, {'x': 1, 'y': 2})
exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
func()
輸出結果為:
60
33
34
itertools模塊中的函數(shù)
Python的內(nèi)建模塊itertools提供了非常有用的用于操作迭代對象的函數(shù)泪电。
itertools模塊提供的全部是處理迭代功能的函數(shù)般妙,它們的返回值不是list,而是Iterator相速,只有用for循環(huán)迭代的時候才真正計算碟渺。
無窮迭代器
Iterator | Arguments | Results | Example |
---|---|---|---|
count() | start, [step] | start, start+step, start+2*step, ... | count(10) --> 10 11 12 13 14 ... |
cycle() | p | p0, p1, ... plast, p0, p1, ... | cycle('ABCD') --> A B C D A B C D ... |
repeat() | elem [,n] | elem, elem, elem, ... endlessly or up to n times | repeat(10, 3) --> 10 10 10 |
“有限”迭代器
Iterator | Arguments | Results | Example |
---|---|---|---|
accumulate() | p [,func] | p0, p0+p1, p0+p1+p2, ... | accumulate([1,2,3,4,5]) --> 1 3 6 10 15 |
chain() | p, q, ... | p0, p1, ... plast, q0, q1, ... | chain('ABC', 'DEF') --> A B C D E F |
chain.from_iterable() | iterable | p0, p1, ... plast, q0, q1, ... | chain.from_iterable(['ABC', 'DEF']) --> A B C D E F |
compress() | data, selectors | (d[0] if s[0]), (d[1] if s[1]), ... | compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F |
dropwhile() | pred, seq | seq[n], seq[n+1], starting when pred fails | dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 |
filterfalse() | pred, seq | elements of seq where pred(elem) is false | filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8 |
groupby() | iterable[, keyfunc] | sub-iterators grouped by value of keyfunc(v) | |
islice() | seq, [start,] stop [, step] | elements from seq[start:stop:step] | islice('ABCDEFG', 2, None) --> C D E F G |
starmap() | func, seq | func(seq[0]), func(seq[1]), ... | starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 |
takewhile() | pred, seq | seq[0], seq[1], until pred fails | takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4 |
tee() | it, n | it1, it2, ... itn splits one iterator into n | |
zip_longest() | p, q, ... | (p[0], q[0]), (p[1], q[1]), ... | zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- |
groupby()函數(shù)
groupby()把迭代器中相鄰的重復元素挑出來放在一起:
for key, group in itertools.groupby('AAABBBCCAAA'):
print(key, list(group))
A ['A', 'A', 'A']
B ['B', 'B', 'B']
C ['C', 'C']
A ['A', 'A', 'A']
實際上挑選規(guī)則是通過函數(shù)完成的,只要作用于函數(shù)的兩個元素返回的值相等突诬,這兩個元素就被認為是在一組的止状,而函數(shù)返回值作為組的key烹棉。
另一個例子
# 按身高歸類
from itertools import *
def height_class(h):
if h>180:
return 'tall'
elif h<160:
return 'short'
else:
return 'middle'
friends = [191, 158, 159, 165, 170, 177, 181, 182, 190]
for m,n in groupby(friends,key = height_class):
print(m)
print(list(n))
作業(yè): 對于一組身高的數(shù)據(jù)(list),利用上面代碼給出的身高標準怯疤,將所以的tall, short, middle歸為一類浆洗。注意與groupby()函數(shù)的區(qū)別。
tee()函數(shù)
把一個迭代器分為n個迭代器, 返回一個元組.默認是兩個
from itertools import *
a = "hello"
c, d, e = tee(iter(a), 3)
for i, j, k in zip(c, d, e):
print(i, j, k)
組合生成器
Iterator | Arguments | Results |
---|---|---|
product() | p, q, ... [repeat=1] | cartesian product, equivalent to a nested for-loop |
permutations() | p[, r] | r-length tuples, all possible orderings, no repeated elements |
combinations() | p, r | r-length tuples, in sorted order, no repeated elements |
combinations_with_replacement() | p, r | r-length tuples, in sorted order, with repeated elements |
product('ABCD', repeat=2) | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD | |
permutations('ABCD', 2) | AB AC AD BA BC BD CA CB CD DA DB DC | |
combinations('ABCD', 2) | AB AC AD BC BD CD | |
combinations_with_replacement('ABCD', 2) | AA AB AC AD BB BC BD CC CD DD |
copy與deepcopy函數(shù)
copy: 淺拷貝(shallow copy), deepcopy: 深拷貝(deep copy).
- 我們尋常意義的復制就是深復制集峦,即將被復制對象完全再復制一遍作為獨立的新個體單獨存在伏社。所以改變原有被復制對象不會對已經(jīng)復制出來的新對象產(chǎn)生影響。
- 而淺復制并不會產(chǎn)生一個獨立的對象單獨存在塔淤,他只是將原有的數(shù)據(jù)塊打上一個新標簽摘昌,所以當其中一個標簽被改變的時候,數(shù)據(jù)塊就會發(fā)生變化高蜂,另一個標簽也會隨之改變聪黎。這就和我們尋常意義上的復制有所不同了。
- 對于簡單的 object备恤,用 shallow copy 和 deep copy 沒區(qū)別
- 復雜的 object稿饰, 如 list 中套著 list 的情況,shallow copy 中的 子list露泊,并未從原 object 真的「獨立」出來喉镰。也就是說,如果你改變原 object 的子 list 中的一個元素惭笑,你的 copy 就會跟著一起變侣姆。這跟我們直覺上對「復制」的理解不同。
例子:
from copy import copy, deepcopy
#origin 里邊有三個元素:1,2,[3, 4]
origin = [1, 2, [3, 4]]
# cop1為淺拷貝沉噩,cop2為深拷貝
cop1 = copy(origin)
cop2 = deepcopy(origin)
# cop1是否與cop2內(nèi)容相同
print(cop1 == cop2)
# cop1是否與cop2為同一個引用
print(cop1 is cop2)
# 改變origin中嵌套列表中的元素
origin[2][0] = "hey"
# 查看輸出
print(origin)
print(cop1)
print(cop2)
# 改變origin中嵌套列表中的元素
origin[1] = "hello"
# 查看輸出
print(origin)
print(cop1)
print(cop2)
輸出結果:
True
False
[1, 2, ['hey', 4]]
[1, 2, ['hey', 4]]
[1, 2, [3, 4]]
[1, 'hello', ['hey', 4]]
[1, 2, ['hey', 4]]
[1, 2, [3, 4]]
模塊
在Python中捺宗,一個Python文件就是一個模塊。
模塊讓你能夠有邏輯地組織你的 Python 代碼段川蒙。
把相關的代碼分配到一個模塊里能讓你的代碼更好用蚜厉,更易懂。
模塊能定義函數(shù)派歌,類和變量弯囊,模塊里也能包含可執(zhí)行的代碼痰哨。
一個簡單的模塊例子:
hello.py
def say_hello(name):
s = 'hello, %s!'%name
return s
使用模塊:
- import module
- from module import ...
import hello
print(hello.say_hello("Lee"))
from hello import say_hello
print(say_hello("Jack"))
os胶果、sys模塊
os模塊
os模塊包含普遍的操作系統(tǒng)功能。
os常用方法及屬性
os.sep 可以取代操作系統(tǒng)特定的路徑分隔符斤斧。windows下為 “\”
os.name字符串指示你正在使用的平臺早抠。比如對于Windows,它是'nt'撬讽,而對于Linux/Unix用戶蕊连,它是'posix'悬垃。
os.getcwd() 函數(shù)得到當前工作目錄,即當前Python腳本工作的目錄路徑甘苍。
os.getenv() 獲取一個環(huán)境變量尝蠕,如果沒有返回none
os.putenv(key, value) 設置一個環(huán)境變量值
os.listdir(path) 返回指定目錄下的所有文件和目錄名。
os.remove(path) 函數(shù)用來刪除一個文件载庭。
os.system(command) 函數(shù)用來運行shell命令看彼。
os.linesep 字符串給出當前平臺使用的行終止符。例如囚聚,Windows使用'\r\n'靖榕,Linux使用'\n'而Mac使用'\r'。
os.curdir: 返回當前目錄('.')
os.chdir(dirname): 改變工作目錄到dirname
os.path常用方法:
os.path.isfile()和os.path.isdir()函數(shù)分別檢驗給出的路徑是一個文件還是目錄顽铸。
os.path.existe()函數(shù)用來檢驗給出的路徑是否真地存在
os.path.getsize(name):獲得文件大小茁计,如果name是目錄返回0L
os.path.abspath(name):獲得絕對路徑
os.path.normpath(path):規(guī)范path字符串形式
os.path.split(path) :將path分割成目錄和文件名二元組返回。
os.path.splitext():分離文件名與擴展名
os.path.join(path,name):連接目錄與文件名或目錄;使用“\”連接
os.path.basename(path):返回文件名
os.path.dirname(path):返回文件路徑
sys模塊
sys模塊提供了一系列有關Python運行環(huán)境的變量和函數(shù)谓松。
sys模塊的常用方法
sys.argv: 實現(xiàn)從終端向程序傳遞參數(shù)星压。
sys.exit([arg]): 程序中間的退出,arg=0為正常退出毒返。
sys.getdefaultencoding(): 獲取系統(tǒng)當前編碼租幕,一般默認為ascii。
sys.setdefaultencoding(): 設置系統(tǒng)默認編碼拧簸,執(zhí)行dir(sys)時不會看到這個方法劲绪,在解釋器中執(zhí)行不通過,可以先執(zhí)行reload(sys)盆赤,在執(zhí)行 setdefaultencoding('utf8')贾富,此時將系統(tǒng)默認編碼設置為utf8。(見設置系統(tǒng)默認編碼 )
sys.getfilesystemencoding(): 獲取文件系統(tǒng)使用編碼方式牺六,Windows下返回'mbcs',mac下返回'utf-8'.
sys.path: 獲取指定模塊搜索路徑的字符串集合畏纲,可以將寫好的模塊放在得到的某個路徑下盗胀,就可以在程序中import時正確找到票灰。
sys.platform: 獲取當前系統(tǒng)平臺屑迂。
sys.stdin, sys.stdout, sys.stderr: stdin , stdout , 以及stderr 變量包含與標準I/O 流對應的流對象. 如果需要更好地控制輸出,而print 不能滿足你的要求, 它們就是你所需要的. 你也可以替換它們, 這時候你就可以重定向輸出和輸入到其它設備( device ), 或者以非標準的方式處理它們
生成器
通過列表生成式惹盼,我們可以直接創(chuàng)建一個列表手报。但是晓淀,受到內(nèi)存限制盏档,列表容量肯定是有限的蜈亩。而且,創(chuàng)建一個包含100萬個元素的列表畅涂,不僅占用很大的存儲空間午衰,如果我們僅僅需要訪問前面幾個元素冒萄,那后面絕大多數(shù)元素占用的空間都白白浪費了尊流。
所以崖技,如果列表元素可以按照某種算法推算出來瞎访,那我們是否可以在循環(huán)的過程中不斷推算出后續(xù)的元素呢装诡?這樣就不必創(chuàng)建完整的list,從而節(jié)省大量的空間渔伯。在Python中锣吼,這種一邊循環(huán)一邊計算的機制,稱為生成器:generator蓝厌。
創(chuàng)建generator的辦法:
- 把一個列表生成式的[]改成()
- yield關鍵字
將列表的[]改成()的例子:
# 列表生成式
L = [x * x for x in range(10)]
print(type(L))
# 創(chuàng)建生成器
g = (x * x for x in range(10))
print(type(g))
# 獲取下一個返回值
# 當沒有更多元素時,會拋出StopIteration錯誤
print(next(g))
print(next(g))
print(next(g))
# for循環(huán)
for n in g:
print(n)
通過yield創(chuàng)建生成器
# 普通方法生成斐波拉契數(shù)列
# 前幾個斐波拉契數(shù)
def fib1(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
fib1(6)
# 通過yield創(chuàng)建生成器
# 注意yield的執(zhí)行流程
def fib2(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
# 將生成器函數(shù)賦值給變量f
f = fib2(6)
print(type(f))
for n in f:
print(n)
generator和函數(shù)的執(zhí)行流程不一樣拓提。函數(shù)是順序執(zhí)行,遇到return語句或者最后一行函數(shù)語句就返回代态。而變成generator的函數(shù),在每次調(diào)用next()的時候執(zhí)行蹦疑,遇到y(tǒng)ield語句返回西雀,再次執(zhí)行時從上次返回的yield語句處繼續(xù)執(zhí)行。
generator執(zhí)行流程的理解:
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)
o = odd()
print(next(o))
print(next(o))
print(next(o))
迭代器
可以直接作用于for循環(huán)的數(shù)據(jù)類型有以下幾種:
集合數(shù)據(jù)類型艇肴,如list豆挽、tuple、dict娘侍、set、str等花鹅;
generator氧腰,包括生成器和帶yield的generator function。
這些可以直接作用于for循環(huán)的對象統(tǒng)稱為可迭代對象:==Iterable==。
可以使用isinstance()判斷一個對象是否是Iterable對象:
from collections import Iterable
# 判斷空列表是否為Iterable對象
# True
print(isinstance([], Iterable))
# 判斷空集合是否為Iterable對象
# True
print(isinstance({}, Iterable))
# 判斷字符是否為Iterable對象
# True
print(isinstance('abc', Iterable))
# 判斷生成器是否為Iterable對象
# True
print(isinstance((x for x in range(10)), Iterable))
# 判斷數(shù)字否為Iterable對象
# False
print(isinstance(100, Iterable))
可以被next()函數(shù)調(diào)用并不斷返回下一個值的對象稱為迭代器:Iterator古拴。
可以使用isinstance()判斷一個對象是否是Iterator對象:
from collections import Iterator
# 判斷生成器是否為Iterator對象
# True
print(isinstance((x for x in range(10)), Iterator))
# 判斷空列表是否為Iterator對象
# False
print(isinstance([], Iterator))
# 判斷空集合是否為Iterator對象
# False
print(isinstance({}, Iterator))
# 判斷字符串是否為Iterator對象
# False
print(isinstance('abc', Iterator))
生成器都是Iterator對象箩帚,但list、dict黄痪、str雖然是Iterable紧帕,卻不是Iterator。
把list桅打、dict是嗜、str等Iterable變成Iterator可以使用iter()函數(shù)。