2018年11月13日 星期二

python- 生成器、迭代器、yield、監聽文件輸入

迭代器:
雙下(雙下滑線)方法: 很少直接調用的方法。一般情況下,是通過其他語法觸發的
可迭代的規則--可迭代協議 含有( __iter__的方法( '__iter__' dir數據)
可迭代的一定可以被for循環。
迭代器一定可迭代,可迭代的通過調用iter()方法就能得到一個迭代器
迭代器特點:
              1.很方便使用,且只能取得所有的數據取一次
              2.節省內存空間

生成器:
.生成器函數--就是我們自己寫的函數
生成器的本質就是迭代器
生成器的表現形式
    1.生成器函數
    2.生成器表達式
生成器函數:
    1.含有yield 關鍵字的函數就是生成器函數
    2.特點:
                 .調用函數的之後函數不執行,返回一個生成器
                 .每次調用next方法的時候可以取得一個值
                 .直到取完最後一個,在執行next會報錯

生成器實現:有一個文件,從文件裡分段讀取內容
readline 取整行的方法
read(10) 取X數量的方法
在讀出來的內容前面加上一個 "****" ,再返回給調用者



執行結果:
哇哈哈0
哇哈哈1
哇哈哈2
哇哈哈3
哇哈哈4
哇哈哈5
哇哈哈6
哇哈哈7
哇哈哈8
哇哈哈9
哇哈哈10
哇哈哈11
哇哈哈12
哇哈哈13
哇哈哈14
哇哈哈15
哇哈哈16
哇哈哈17
哇哈哈18
哇哈哈19



從生成器中取值的幾個方法
                   next
                   fot
                   數據類型的強制轉換:  佔用內存





1.使用return  方法
#生成器函數def  generator():
    print(1)
    return  'a'
ret  =  generator()
print(ret)

執行結果:
1

a



.yield關鍵字

.yield的函數不再是一個普通的函數,而是一個生成器generator,可用於迭代。
.類似returm  的關鍵字,迭代時遇到就會返回yieldc右邊(後方)的值。在執行下次迭代時會從上一次遇yieldc的後方程序(下一行)開始執行。
.yield的函數可以用在for循環中以及函數的參數上,只要這個函數允許迭代參數,array.extend函數,它的原型是array.extend(iterable)。
.yield不可以跟returm 共用,且需要寫在函數內


使用yield
#生成器函數def  generator():
    print(1)
    yield"a"#生成器函數:執行之後會得到一個生成器作為返回值
ret  =  generator()
print(ret)
print(ret.__next__())



.當執行到yield 時會停止然後傳回值,如果再次執行會再從上次的地方跳行執行
def   gemerator():
    print(1)
    yield "a"    print(2)
    yield "b"g  = gemerator()
ret=g.__next__()
print(ret)
ret=g.__next__()
print(ret)

執行結果:
1
a
2
b



.也可以使用for來接收yield的值
def   gemerator():
    print(1)
    yield "a"    print(2)
    yield "b"g  = gemerator()
for i  in g:
    print(i)
# ret=g.__next__()# print(ret)# ret=g.__next__()# print(ret)
執行結果:
1
a
2
b



.可以快速的處裡大量數據 

def  eess():
    for  i  in range(2000000000):
        yield "執行第%s"%i

g =  eess()
for i  in g:
    print(i)



.限制生成數量,如果再次執行可以在往下接取
def  eess():
    for  i  in range(2000000000):
        yield "執行第%s"%i

g =  eess()
count = 0for i  in g:
    count += 1    print(i)
    if count >50:
        break
g =  eess()
 
for i  in g:
    count += 1    print(i)
    if count >100:
        break

.列表是一個可迭代對象,如果要讓使用迭代要轉換成迭代器

l  =  [1,2,3,4,5]
for  i  in l:
    print(i)
    if i == 2:
        breakfor i  in l:
    print(i)
執行結果:
1
2
1
2
3
4

5


.生成器的引用互不相同,可看到下面g跟g111是不同的生成器
def  eecco():
    for i  in range(100):
        yield  "執行程序%s" %i
g =  eecco()
g111 = eecco()
print(g.__next__())
print(g.__next__())
print(g.__next__())
print('另一個',g111.__next__())
print('另一個',g111.__next__())

.監聽file文件的內容並且打印出來

f  =  open('file',encoding="utf-8")
while True:
    line  = f.readline()
    if line:


將原本監聽功能改成函數

def tail(foodde):
    f  =  open(foodde,encoding="utf-8")
    while True:
        line  = f.readline()
        if line:
            print(line.strip())

tail('file')

.將監聽器改成生成器特性,並增加可以過濾文字功能

def tail(foodde):
    f  =  open(foodde,encoding="utf-8")
    while True:
        line  = f.readline()
        if line.strip():
            yield   line.strip()

g = tail('file')
for i in g:
    if "python" in i:
        print("****",i)
執行結果:
**** python

**** python.55









沒有留言:

張貼留言