**生成器 (generator)**
在 Python 中一邊循環一邊計算的方式稱為生成器 ( generator )。
當我們需要使用無窮無盡的數據的時候,由于電腦機器的內存是有限的,不可能一次性存儲那么多的數據,我們就可以根據某種規律計算出下一個數據的值,我們只需保存算法,這樣就節省大量的空間,而不需要保存真實的海量數據,再在循環中不斷推算下一個數據值的思想就誕生了生成器 ( generator )。
**生成器的創建常用方法**
方法一:把一個列表生成式的 [ ] 改成 ( ),就創建了一個生成器 ( generator )。
~~~
>>> _list = [ i for i in range(3)]
>>> _list
[0, 1, 2]
>>> gene = (i for i in range(3))
>>> gene
<generator object <genexpr> at 0x7f495742a6d0>
~~~
使用列表生成式生成的列表我們可以直接打印出列表中的每一個元素,但是生成的生成器對象我們卻只得到了一個內存地址,那如何獲取生成器對象中的元素呢?
通過 next() 方法打印生成器中的元素,直到最后拋出 StopIteration 錯誤表示無法繼續返回下一個值了。
~~~
>>> next(gene)
0
>>> next(gene)
1
>>> next(gene)
2
>>> next(gene) #拋出 StopIteration 錯誤
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
~~~
當然我們也可以使用 for 循環打印生成器中的元素
~~~
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
gene = (i for i in range(3))
for i in gene:
print(i)
~~~
方法二:在函數定義中使用了 yield 關鍵字,那么這個函數就不再是一個普通函數,而是一個生成器 ( generator )。
生成器 ( generator ) 和普通函數的執行流程不一樣。函數是順序執行,遇到 return 語句或者最后一行函數語句就返回。而生成器 ( generator ) 的函數,在每次調用 next() 的時候執行,遇到 yield 語句返回,再次執行時從上次返回的 yield 語句處繼續執行 , 更簡單點理解生成器就是一個迭代器。
**實例說明**
~~~
>>>def info():
... print('Python')
... yield 1
... print('PHP')
... yield 2
... print('Java')
... yield 3
...
~~~
調用時,首先要生成一個生成器 ( generator ) 對象,然后用 next() 函數不斷獲得下一個返回值:
~~~
>>> g = info()
>>> next(g) #第一次調用
Python
1
>>> next(g) #第二次調用
PHP
2
>>> next(g) #第三次調用
Java
3
>>> next(g) #拋出 StopIteration 錯誤
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
~~~
可以看出, info() 已經不是一個普通函數而是生成器,在調用過程中遇到 yield 就中斷,下次又在中斷出繼續執行。執行 3 次 yield 后,已經沒有 yield 可以執行了,所以,第 4 次調用 next(g) 就拋出 StopIteration 的錯誤。
實例使用 yield 實現斐波那契數列
~~~
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
def fibonacci(n): # 斐波那契生成器函數
a, b, num = 0, 1, 0
while True:
if (num > n):
return
yield a
a, b = b, a + b
num += 1
g = fibonacci(3) # g是一個由斐波那契生成器函數返回迭代器
while True:
try:
print (next(g), end=",")
except StopIteration:
break
~~~
執行結果
~~~
0,1,1,2,
~~~
當然在實際開發中我們很少使用 while 去循環迭代器,因為使用 for 進行迭代更方便。
- 跟老司機學Python
- 了解Python
- 1、python簡介
- 2、Python發展史
- 3、Python特點
- 4、Python解釋器
- 入坑Python
- 1、Python環境搭建
- 2、設置環境變量
- 3、開始使用Python
- 4、運行Python程序
- 掌握Python基礎
- Python基礎知識
- Python運算符
- 算術運算符
- 比較運算符
- 賦值運算符
- 邏輯運算符
- 位運算符
- 成員運算符
- 身份運算符
- 運算符優先級
- Python的變量與常量
- Python數據類型
- Number數值
- String字符串
- List列表
- Tuple元組
- Dictionary字典
- Set集合
- Python流程控制語句
- 條件判斷
- 循環控制
- Python函數
- 1、函數是什么
- 2、函數的定義
- 3、函數的參數
- 4、函數的調用
- 5、嵌套函數
- 6、遞歸函數
- 7、匿名函數
- 8、函數式編程
- 9、高階函數
- 1、map
- 2、reduce
- 3、filter
- 4、sorted
- 10、返回函數
- 11、偏函數
- Python文件IO操作
- 標準輸入輸出
- 讀寫文件
- with讀寫文件
- Python高級特性
- 1、列表生成式
- 2、迭代器
- 3、生成器
- 4、裝飾器
- Python模塊初探
- 1、模塊與包
- 2、創建模塊
- 3、模塊中的作用域
- 4、模塊的導入
- Python面向對象編程
- 類與對象
- 類的定義及使用
- 面向對象特性
- 類中的訪問域
- 查看對象詳情
- Python面向對象進階
- 類中的方法
- 類中的特殊成員
- 限制對象的屬性
- 再聊多繼承
- 裝x式創建類
- 創建元類
- Python內置模塊
- os模塊
- sys模塊
- random模塊
- time模塊
- datetime模塊
- shutil模塊
- collections模塊
- base64模塊
- json模塊
- hashlib模塊
- xml模塊
- 1. SAX解析XML
- 2. DOM解析XML
- 3. ElementTree解析XML
- urllib模塊
- logging模塊
- re模塊
- Python第三方模塊
- Pillow與PIL
- Requests
- Tablib
- Xpinyin
- Chardet
- Pycurl
- Virtualenv
- Python操作數據庫
- Mysql操作
- Sqllite操作
- Mongodb操作
- Redis操作
- Python的GUI編程
- Python中GUI的選擇
- Tkinter
- wxPython
- Socket網絡編程
- Socket網絡編程簡聊
- Socket內建方法
- TCP協議編程
- UDP協議編程
- TCP與UDP
- Python電子郵件
- SMTP發郵件
- POP3收郵件
- IMAP收郵件
- 進程線程
- 進程與線程
- 進程編程
- 使用進程池
- 進程間的通信
- 線程編程
- 使用線程鎖
- Python的GIL
- Web編程
- WSGI介紹
- Web框架
- Flask使用
- 模板jinjia2使用
- 項目結構規劃
- 異步與協程
- 概念掃盲
- 異步IO進化之路
- 協程是什么
- yield協程編程
- yield from
- asyncio
- async與await
- aiohttp之client
- aiphttp之server
- 網絡爬蟲
- 網絡爬蟲簡聊
- Beautiful Soup模塊的使用
- pyquery 模塊的使用
- selenium模塊的使用
- 爬取段子實例
- 錯誤與調試
- 錯誤
- 錯誤處理
- 拋出錯誤
- 高效的調試
- Python重要語句
- pass語句
- return語句
- Python開發必知
- pip使用詳解
- 如何對列表進行迭代
- 如何對字典進行迭代
- 字符串格式化
- 知識擴展
- 網絡模型
- GUI是什么