Python進階筆記

  1. 列表生成式
  2. 函數(shù)的參數(shù)類型
  3. lambda函數(shù)
  4. map, reduce, filter, sorted函數(shù)
  5. eval, exec, join, zip函數(shù)
  6. itertools中的函數(shù)
  7. copy與deepcopy函數(shù)
  8. 模塊
  9. os团滥、sys模塊
  10. 迭代器
  11. 生成器
  12. 迭代器

參考網(wǎng)站:

  1. Python3教程: https://www.python-course.eu/python3_course.php
  2. Python之函數(shù)參數(shù)的使用:https://blog.csdn.net/jclian91/article/details/78309522
  3. 廖雪峰Python教程: https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
  4. Python之淺談exec函數(shù): https://blog.csdn.net/jclian91/article/details/80076512
  5. Python官網(wǎng)的itertools說明: https://docs.python.org/3.6/library/itertools.html
  6. Python-copy()與deepcopy()區(qū)別: https://blog.csdn.net/qq_32907349/article/details/52190796
  7. 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ù)。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挺尾,一起剝皮案震驚了整個濱河市鹅搪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌遭铺,老刑警劉巖涩嚣,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異掂僵,居然都是意外死亡航厚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門锰蓬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來幔睬,“玉大人,你說我怎么就攤上這事芹扭÷槎ィ” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵舱卡,是天一觀的道長辅肾。 經(jīng)常有香客問我,道長轮锥,這世上最難降的妖魔是什么矫钓? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮舍杜,結果婚禮上新娜,老公的妹妹穿的比我還像新娘。我一直安慰自己既绩,他們只是感情好概龄,可當我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著饲握,像睡著了一般私杜。 火紅的嫁衣襯著肌膚如雪蚕键。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天衰粹,我揣著相機與錄音锣光,去河邊找鬼。 笑死寄猩,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的骑疆。 我是一名探鬼主播田篇,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼箍铭!你這毒婦竟也來了泊柬?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤诈火,失蹤者是張志新(化名)和其女友劉穎兽赁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冷守,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡刀崖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了拍摇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亮钦。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖充活,靈堂內(nèi)的尸體忽然破棺而出蜂莉,到底是詐尸還是另有隱情,我是刑警寧澤混卵,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布映穗,位于F島的核電站,受9級特大地震影響幕随,放射性物質(zhì)發(fā)生泄漏蚁滋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一赘淮、第九天 我趴在偏房一處隱蔽的房頂上張望枢赔。 院中可真熱鬧,春花似錦拥知、人聲如沸踏拜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽速梗。三九已至肮塞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間姻锁,已是汗流浹背枕赵。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留位隶,地道東北人拷窜。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像涧黄,于是被迫代替她去往敵國和親篮昧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 〇笋妥、前言 本文共108張圖懊昨,流量黨請慎重! 歷時1個半月春宣,我把自己學習Python基礎知識的框架詳細梳理了一遍酵颁。 ...
    Raxxie閱讀 18,952評論 17 410
  • http://python.jobbole.com/85231/ 關于專業(yè)技能寫完項目接著寫寫一名3年工作經(jīng)驗的J...
    燕京博士閱讀 7,575評論 1 118
  • pyton review 學習指南 https://www.zhihu.com/question/29138020...
    孫小二wuk閱讀 1,046評論 0 2
  • 她,叫寧寧月帝,是個喜歡叫自己萌妹子的女孩躏惋。和她相遇的一個夏天的傍晚,我想我這輩子都不會忘記那天發(fā)生的每一幕嚷辅。擔心有一...
    打呼嚕的小餅干閱讀 83評論 0 0
  • 桐枝疏影碎流光其掂,地枕天高午夢長。 我欲來尋華胥境潦蝇,馳風暢飲五云漿款熬。 注:華胥境,典出《列子·黃帝》攘乒,華胥境即指夢境...
    紫風鈴_閱讀 550評論 64 44