Python迭代器與生成器研究記錄

Python迭代器與生成器研究記錄

前言

迭代器肯定是可迭代對象,但是可迭代對象不一定是迭代器,生成器一定是迭代器,但是迭代器不一定是生成器
生成器是特殊的迭代器,所以生成器一定是迭代器,迭代器一定是可迭代對象
我們平常接觸最多的對象中,字符串,字典,列表,集合,元組和open打開的文件對象等都是可迭代的對象因為他們都有__iter__()方法,可以遍歷
需要注意的是,我們平常接觸最多的對象中,字符串,字典,列表,集合,元組等都不是迭代器因為他們都沒有__next__()方法,但是open打開的文件對象卻是一個迭代器對象

# obj.__next__()方法 等價于next(obj)
# obj.__iter__()方法 等價于iter(obj)test_list = [10, 20, 30, 40]
generator_obj = (i for i in test_list)
print(generator_obj) # <generator object <genexpr> at 0x0000029852C98C00>
print(generator_obj.__next__())  # 10
print(generator_obj.__iter__())  # <generator object <genexpr> at 0x0000027411078C00>
print(next(generator_obj))  # 20
print(iter(generator_obj))  # <generator object <genexpr> at 0x0000027411078C00>

可迭代對象

1.只要內部有__iter__()方法的對象就是可迭代對象如 字符串,字典,列表集合,元組,包括open打開的文件對象也都是可迭代對象
2.或者可以這樣說,只要可以轉換成迭代器的對象就是可迭代對象

這些都是可迭代對象

test_list = [1, 3, 4, 7]
test_list.__iter__()
test_str = "test_str"
test_str.__iter__()
test_dict = {"1":12}
test_dict.__iter__()
test_set = {"1", "4", "898"}
test_set.__iter__()
with open("file_path", "r") as file_obj:file_obj.__iter__()

可迭代對象調用__iter__()方法會返回一個迭代器,代碼如下

test_list = [1, 3, 4, 7]
print(test_list.__iter__())
print(type(test_list.__iter__()))
# 可迭代對象調用__iter__()方法返回的就是一個迭代器
# <list_iterator object at 0x000001CEB3AD5518>
# <class 'list_iterator'>

迭代器

迭代器就是有__iter__()方法和__next()__方法的對象,所以迭代器肯定是可迭代對象,但是可迭代對象不一定是迭代器
迭代器對象調用__next__()方法每次會拿到迭代器里面的一個值并返回,直到全部拿完會報錯StopIteration
迭代器對象調用__iter__()方法返回的是迭代器本身(和沒調用一樣),可迭代但是非迭代器的對象調用__iter__()方法也是返回的是基于這個對象的迭代器

需要注意的是,我們平常接觸最多的對象中,字符串,字典,列表,集合,元組等都不是迭代器因為他們都沒有__next__()方法,但是open打開的文件對象卻是一個迭代器對象

# 迭代器的一個特征就是有__next__()方法
test_list = [1, 3, 4, 7]
# 可迭代對象調用__iter__()方法返回的就是一個迭代器
list_iterator_obj = test_list.__iter__()# 迭代器調用_next__()方法每次就會拿出這個迭代器里面的一個值,直到全部拿完會報錯
for i in range(5):print(list_iterator_obj.__next__())# 1
# 3
# 4
# 7
# Traceback (most recent call last):
#   File "C:/Users/xxx/Desktop/python_test_dir/test_4.py", line 10, in <module>
#     print(list_iterator_obj.__next__())
# StopIteration

迭代器對象調用__iter__()方法返回的是他自己,和沒調用一樣

# 迭代器的特征就是有__next__()方法
test_list = [1, 3, 4, 7]
# 可迭代對象調用__iter__()方法返回的就是一個迭代器
list_iterator_obj = test_list.__iter__()# 迭代器對象調用__iter__()方法返回的是他自己,和沒調用一樣
list_iterator_obj2 = list_iterator_obj.__iter__()
print(list_iterator_obj2 is list_iterator_obj)      # Trueprint(list_iterator_obj.__next__())     # 1
print(list_iterator_obj.__next__())     # 3
# 注意這里會返回此迭代器對象直接理解為是 list_iterator_obj = list_iterator_obj (因為是返回自己,所以里面剩余的值狀態也是一樣的)
list_iterator_obj = list_iterator_obj.__iter__()
print(list_iterator_obj.__next__())     # 4
print(list_iterator_obj.__next__())     # 7

for 循環遍歷的本質可以理解成
1,每次調用此對象的__iter__()方法返回這個對象的迭代器版本
2,調用第一步返回的此迭代器版本的__next__()方法拿出里面的一個值
3,循環執行第二步直到所有元素拿完for 循環捕獲結束時拋出的StopIteration異常并結束

生成器

生成器可以理解為自己定義的一個迭代器,可以自定義一個生成器,生成器定義有兩種方法
1.函數yield關鍵字返回,含有yield關鍵字的函數會返回一個生成器對象,對此對象調用__next__()方法會執行此函數對應的yield關鍵字之前的代碼并且返回yield關鍵字字后的返回值然后截止,下次調用__next__()方法又可以在上次的基礎上繼續執行
2.生成器表達式(我們以為的"元組推導式"就是生成器表達式,需要注意元組因為是不可變的所以元組沒有推導式,類似元組推導式的形式其實是生成器表達式)

函數yield關鍵字生成器

def test():print("第一次執行")yield 1print("第二次執行")yield 2print("第三次執行")yield 3print("第四次執行")yield 4print("最后一次執行")# test函數返回一個生成器對象
generator_obj = test()print(generator_obj)  # <generator object test at 0x000001B393528C00>print(generator_obj.__next__())
# 第一次執行
# 1
print(generator_obj.__next__())
# 第二次執行
# 2
print(generator_obj.__next__())
# 第三次執行
# 3
print(generator_obj.__next__())
# 第四次執行
# 4
print(generator_obj.__next__())
# 最后一次執行
# Traceback (most recent call last):
#   File "C:/Users/xxx/Desktop/python_test_dir/test_4.py", line 51, in <module>
#     print(generator_obj.__next__())
# StopIteration

生成器表達式

test_list = [10, 20, 30, 40]
generator_obj = (i for i in test_list)
print(generator_obj) # <generator object <genexpr> at 0x0000029852C98C00>
print(generator_obj.__next__())  # 10
print(generator_obj.__next__())  # 20
print(generator_obj.__next__())  # 30
print(generator_obj.__next__())  # 40

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210835.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210835.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210835.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

YOLOv8分割訓練及分割半自動標注

YOLOv8是基于目標檢測算法YOLOv5的改進版,它在YOLOv5的基礎上進行了優化和改進,加入了一些新的特性和技術,如切片注意力機制、骨干網絡的選擇等。 本文以yolov8-seg為基準,主要整理分割訓練流程及使用v8分割模型進行半自動標注的過程。 一、v8-seg訓練 1.1 環境配置 github…

【Altera】平臺設計器互連會回壓 AXI 接口怎么辦

說明 實現 AXI 接口的所有組件都具有發行或接受能力設置。每當互連檢測到管理器&#xff08;主管理器&#xff09;發出的事務多于管理器的發行容量設置時&#xff0c;互連將通過斷言 AxREADY 向管理器背壓。每當互連檢測到從屬&#xff08;從站&#xff09;接收的事務多于從屬的…

實用篇 | 一文快速構建人工智能前端展示streamlit應用

----------------------- &#x1f388;API 相關直達 &#x1f388;-------------------------- &#x1f680;Gradio: 實用篇 | 關于Gradio快速構建人工智能模型實現界面&#xff0c;你想知道的都在這里-CSDN博客 &#x1f680;Streamlit :實用篇 | 一文快速構建人工智能前端展…

Activity從下往上彈出視差效果實現

其實這篇文章是轉至簡書上的大佬的&#xff0c;加上我自己的代碼實踐了下發現可行&#xff0c;于是就分享下 先看效果 介紹: 其實有很多方法都可以實現這種效果&#xff0c;popwindow&#xff0c;Dialog&#xff0c;BottomSheetDialogFragment&#xff0c;BottomSheetDialog等…

Linux 安裝 Gitea.md

### 從官網下載git 和 gitea Git下載地址: https://mirrors.edge.kernel.org/pub/software/scm/git/ 下載 git-2.43.0.tar.gz: https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.43.0.tar.gz Gitea下載地址: https://dl.gitea.com/gitea/ 下載 linux-arm64 的二進…

鏈表OJ—相交鏈表

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言 1、相交鏈表的題目&#xff1a; 方法講解&#xff1a; 圖文解析&#xff1a; 代碼實現&#xff1a; 總結 前言 世上有兩種耀眼的光芒&#xff0c;一種是正在升…

15.Java程序設計-基于SSM框架的微信小程序校園求職系統的設計與實現

摘要&#xff1a; 本研究旨在設計并實現一款基于SSM框架的微信小程序校園求職系統&#xff0c;以提升校園求職流程的效率和便捷性。通過整合微信小程序平臺和SSM框架的優勢&#xff0c;本系統涵蓋了用戶管理、職位發布與搜索、簡歷管理、消息通知等多個功能模塊&#xff0c;為…

愛智EdgerOS之深入解析AI圖像引擎如何實現AI視覺開發

一、前言 AI 視覺是為了讓計算機利用攝像機來替代人眼對目標進行識別&#xff0c;跟蹤并進一步完成一些更加復雜的圖像處理。這一領域的學術研究已經存在了很長時間&#xff0c;但直到 20 世紀 70 年代后期&#xff0c;當計算機的性能提高到足以處理圖片這樣大規模的數據時&am…

ArkUI組件

目錄 一、概述 聲明式UI 應用模型 二、常用組件 1、Image&#xff1a;圖片展示組件 示例 配置控制授權申請 2、Text&#xff1a;文本顯示組件 示例 3、TextInput&#xff1a;文本輸入組件 示例 4、Button&#xff1a;按鈕組件 5、Slider&#xff1a;滑動條組件 …

Swagger PHP Thinkphp 接口文檔

安裝 1. 安裝依賴 composer require zircote/swagger-php 2. 下載Swagger UI git clone https://github.com/swagger-api/swagger-ui.git 3. 復制下載好的Swagger UI 中的dist目錄到public目錄中&#xff0c;修改目錄名稱 cp -rf swagger-ui/dist /home/htdocs/public/ m…

vue中設置滾動條的樣式

在vue項目中&#xff0c;想要設置如下圖中所示滾動條的樣式&#xff0c;可以采用如下方式&#xff1a; ?// 直接寫在vue.app文件中 ::-webkit-scrollbar {width: 3px;height: 3px; } ::-webkit-scrollbar-thumb { //滑塊部分// border-radius: 5px;background-color: #1890ff;…

【智能家居】智能家居項目

智能家居項目目錄 項目目錄結構 完整而典型的項目目錄結構 CMake模板 CMake編譯運行 README.md 項目說明文檔 智能家居項目目錄 【智能家居】面向對象編程OOP和設計模式(工廠模式) 【智能家居】一、工廠模式實現繼電器燈控制 【智能家居】二、添加火災檢測模塊&#xff08;…

4-Docker命令之docker ps

1.docker ps介紹 docker ps命令是用來列出容器的相關信息 2.docker ps用法 docker ps [參數] [rootcentos79 ~]# docker ps --helpUsage: docker ps [OPTIONS]List containersAliases:docker container ls, docker container list, docker container ps, docker psOptions…

【重點】【二叉樹】199.二叉樹的右視圖

題目 法1:層次遍歷 最佳方法&#xff0c;牢記&#xff01;&#xff01;&#xff01; class Solution {public List<Integer> rightSideView(TreeNode root) {List<Integer> res new ArrayList<>();if (root null) {return res;}Queue<TreeNode> q…

Java 克隆:復制構造函數與克隆

為了實現克隆&#xff0c;我們需要配置我們的類并遵循以下步驟&#xff1a; 在我們的類或其超類或接口中實現 Cloneable 接口。 定義一個應處理 CloneNotSupportedException&#xff08;拋出或記錄&#xff09;的 clone() 方法。 并且&#xff0c;在大多數情況下&#xff0c;我…

Ubuntu上svn基本使用(gitee提交下載)

目錄 環境準備 1. 獲取代碼到本地 直接獲取 獲取代碼時加入用戶名密碼 指定版本更新 2. 提交代碼 3. 展示代碼列表 4. 添加代碼文件(目錄) 5. 刪除gitee倉庫中的文件 參考文檔鏈接 環境準備 當前操作系統為Ubuntu22.04LTS gitee 創建倉庫時 需要打開svn的支持 sudo…

GoLong的學習之路,進階,微服務之使用,RPC包(包括源碼分析)

今天這篇是接上上篇RPC原理之后這篇是講如何使用go本身自帶的標準庫RPC。這篇篇幅會比較短。重點在于上一章對的補充。 文章目錄 RPC包的概念使用RPC包服務器代碼分析如何實現的&#xff1f;總結Server還提供了兩個注冊服務的方法 客戶端代碼分析如何實現的&#xff1f;如何異步…

nginx配置正向代理支持https

操作系統版本&#xff1a; Alibaba Cloud Linux 3.2104 LTS 64位 nginx版本&#xff1a; nginx-1.25.3 1. 下載軟件 切換目錄 cd /server wget http://nginx.org/download/nginx-1.25.3.tar.gz 1.1解壓 tar -zxvf nginx-1.25.3.tar.gz 1.2切換到源碼所在目錄…

【探索Linux】—— 強大的命令行工具 P.21(多線程 | 線程同步 | 條件變量 | 線程安全)

閱讀導航 引言一、線程同步1. 競態條件的概念2. 線程同步的概念 二、條件變量1. 條件變量函數?使用前提&#xff08;1&#xff09;初始化條件變量&#xff08;2&#xff09;等待條件滿足&#xff08;3&#xff09;喚醒等待pthread_cond_broadcast()pthread_cond_signal() &…