日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gj9 迭代器和生成器

發布時間:2024/9/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gj9 迭代器和生成器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

9.1 python的迭代協議

list內部實現了__iter__()協議(魔法函數),是可迭代對象,但還不是迭代器(迭代器需要實現__next__協議)

生成器實現了__iter__(),__next__()協議,因此是迭代器。但迭代器不一定是生成器(不具有生成器的方法協議)

#什么是迭代協議 #迭代器是什么? 迭代器是訪問集合內元素的一種方式, 一般用來遍歷數據 #迭代器和以下標的訪問方式不一樣, 迭代器是不能返回的, 迭代器提供了一種惰性方式數據的方式 #[] list , __iter__from collections.abc import Iterable, Iterator a = [1,2] iter_rator = iter(a) print (isinstance(a, Iterable)) print (isinstance(a, Iterator)) print (isinstance(iter_rator, Iterator))--- True False True

9.2 什么是迭代器和可迭代對象

from collections.abc import Iterator class Company(object):def __init__(self, employee_list):self.employee = employee_listdef __iter__(self): # 可迭代對象,實現了__iter__return MyIterator(self.employee) # iter(可迭代對象) 方法 會調用反回迭代器# def __getitem__(self, item): # 當沒有定義__iter__協議for循環就會將定義的getitem變成迭代器# return self.employee[item] # 退化為迭代器# 可迭代對象不要去實現__next__class MyIterator(Iterator): # 迭代器 實現了__next__def __init__(self, employee_list):self.iter_list = employee_listself.index = 0def __next__(self):#真正返回迭代值的邏輯 #實現原理try:word = self.iter_list[self.index]except IndexError:raise StopIterationself.index += 1return wordif __name__ == "__main__":company = Company(["tom", "bob", "jane"])my_itor = iter(company)for item in company:print (item)# --- tom bob jane

9.3 生成器函數使用

#生成器函數,函數里只要有yield關鍵字 def gen_func():yield 1yield 2yield 3def func():return 1if __name__ == "__main__":#生成器對象, python編譯字節碼的時候就產生了,gen = gen_func() # <generator object gen_func at 0x000001CD083334F8>print(gen)for value in gen:print (value)# --- <generator object gen_func at 0x000001CD08333570> 1 2 3 # --- ? ? # 斐波拉契 0 1 1 2 3 5 8 # 惰性求值, 延遲求值提供了可能def fib(index): # 第幾個數if index <= 2:return 1else:return fib(index-1) + fib(index-2)def fib2(index): # 打印前幾個數re_list = []n,a,b = 0,0,1while n<index:re_list.append(b)a,b = b, a+bn += 1return re_list print(fib(10)) print(fib2(10)) # --- 55 [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] # ---def gen_fib(index):n,a,b = 0,0,1while n<index:yield ba,b = b, a+bn += 1for data in gen_fib(10):print (data)# --- 1 1 2 3 5 8 13 21 34 55

9.4 生成器的原理

#1.python中函數的工作原理def foo():bar() def bar():pass#python.exe會用一個叫做 PyEval_EvalFramEx(c函數)去執行foo函數, 首先會創建一個棧幀(stack frame) """ python一切皆對象,棧幀對象, 字節碼對象 當foo調用子函數 bar, 又會創建一個棧幀 所有的棧幀都是分配在堆內存上,這就決定了棧幀可以獨立于調用者存在 """ import dis print(dis.dis(foo)) #---5 0 LOAD_GLOBAL 0 (bar)2 CALL_FUNCTION 04 POP_TOP6 LOAD_CONST 0 (None)8 RETURN_VALUE None #--- import inspect frame = None def foo():bar() def bar():global frameframe = inspect.currentframe()foo() print(frame.f_code.co_name) #棧針 caller_frame = frame.f_back # 調用他的棧針 print(caller_frame.f_code.co_name)# --- bar foo

def gen_func():yield 1name = "lewen"yield 2age = 30return "imooc"import dis gen = gen_func() print (dis.dis(gen))# ---2 0 LOAD_CONST 1 (1)2 YIELD_VALUE4 POP_TOP3 6 LOAD_CONST 2 ('lewen')8 STORE_FAST 0 (name)4 10 LOAD_CONST 3 (2)12 YIELD_VALUE14 POP_TOP5 16 LOAD_CONST 4 (30)18 STORE_FAST 1 (age)6 20 LOAD_CONST 5 ('imooc')22 RETURN_VALUE None # ---print(gen.gi_frame.f_lasti) print(gen.gi_frame.f_locals) next(gen) print(gen.gi_frame.f_lasti) print(gen.gi_frame.f_locals) next(gen) print(gen.gi_frame.f_lasti) print(gen.gi_frame.f_locals)# --- -1 {} 2 {} 12 {'name': 'lewen'}

9.5 通過UserList來看生成器的應用


from collections import UserList # 用Python實現的list

??

9.6 生成器實現大文件讀取

# 500G, 特殊 全部在 一行,由特殊分割符分割 # 一次性讀取太大,按分隔符讀取 def myreadlines(f, newline):buf = "" # 緩存while True:while newline in buf:pos = buf.index(newline)yield buf[:pos] # 將第一個分隔符之前的數據yield 出去buf = buf[pos + len(newline):] # 丟棄掉yield的數據,如果buf中還有分隔符就繼續處理,chunk = f.read(4096) # 沒有就繼續讀新的4096個字節if not chunk:# 說明已經讀到了文件結尾yield bufbreakbuf += chunkwith open("input.txt") as f:for line in myreadlines(f, "{|}"):print(line)

總結

以上是生活随笔為你收集整理的gj9 迭代器和生成器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。