【原創】collections庫 和 python的 生成式 生成器 迭代器
其他--需要研究的資料
參考資料-- 內容太多,以後繼續學
https://www.cnblogs.com/wj-1314/p/8490822.html
https://www.cnblogs.com/pengsixiong/p/5841923.html
https://www.jianshu.com/p/078a985fe80f
容器container
(1)str ,list ,tuple ,set ,dict都是 container
(2)container都是Iterable
collections 庫
匯入,需要單獨匯入
import collections #如果要使用Iterable 等,還需要單獨匯入
from collections import Iterable #記住Iterable 大寫,不是iterable
from collections import Iterator #記住Iterator 大寫
Iterable 可迭代物件
凡是可作用於for迴圈的物件都是Iterable型別
凡是可作用於next()函式的物件都是Iterator型別
可迭代物件:這個物件本身可以提供有限數量的內部元素供迴圈語句遍歷,所以container都符合
實測
測試:str ,list ,tuple ,set ,dict都是 Iterable, 只有int,float等不是
測試:str ,list ,tuple ,set ,dict,包括int, float 都不是 Iterator
>>> listA=[1,2,3]
>>> tupleA=(1,2,3)
>>> dictA={"a":1,"b":2}
>>> setA={1,2,3}
>>> from collections import Iterable
Warning (from warnings module):
File "__main__", line 1
DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
>>> from collections import Iterator
>>> print(isinstance(listA,Iterable),isinstance(tupleA,Iterable),isinstance(dictA,Iterable),isinstance(setA,Iterable))
True True True True
>>> isinstance("abc",Iterable)
True
>>> isinstance(123,Iterable)
False
>>> print(isinstance(listA,Iterator),isinstance(tupleA,Iterator),isinstance(dictA,Iterator),isinstance(setA,Iterator),isinstance(strA,Iterator),isinstance(intA,Iterator),isinstance(floatA,Iterator))
False False False False False False False
迭代器
迭代器:自動地 將自己變數名所指向的記憶體中的地址中的元素,根據迴圈語句的需要逐次迴圈
- 生成器generator
- iter() 轉這些物件:str ,list ,tuple ,set ,dict
- 一定可以被 next() 全域性函式呼叫
iter(Iterable_obj) #可迭代物件
>>> listB=iter(listA)
>>> tupleB=iter(tupleA)
>>> dictB=iter(dictA)
>>> setB=iter(setA)
>>> strB=iter(strA)
>>> print(isinstance(listB,Iterator),isinstance(tupleB,Iterator),isinstance(dictB,Iterator),isinstance(setB,Iterator),isinstance(strB,Iterator),isinstance(intA,Iterator),isinstance(floatA,Iterator))
True True True True True False False
>>> listB
<list_iterator object at 0x0000000003373278>
>>> print(listB)
<list_iterator object at 0x0000000003373278>
列表生成式
列表生成式就是生成一個特定列表的表示式,基本語法:[exp for iter_var in iterable],例如:
這樣寫比用迴圈語句來寫要簡單很多。注意不要忘記把式子用中括號括起來,因為你要生成的是列表。
>>> listA1=[2*a for a in range(10)]
>>> listA1
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> listA2=[a*b+1 for a in range(10) for b in range(5)]
>>> listA2
[1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 1, 3, 5, 7, 9, 1, 4, 7, 10, 13, 1, 5, 9, 13, 17, 1, 6, 11, 16, 21, 1, 7, 13, 19, 25, 1, 8, 15, 22, 29, 1, 9, 17, 25, 33, 1, 10, 19, 28, 37]
>>> listA3=[2*a for a in range(10) if a%2==1]
>>> listA3
[2, 6, 10, 14, 18]
>>> genA1=(2*a for a in range(10) if a%2==0)
>>> genA1
<generator object <genexpr> at 0x0000000002F13570>
>>>
生成器 generator(是一種特殊的迭代器)
為什麼說生成器也是迭代器
因為generator,實現了__iter__與_next_,所以一定是iterator
可以通過查 dir(obj)
比如list,下面是完全生成list內容--佔用空間
(1) list 直接定義
(2)list() 轉為list
(3)列表生成式,listA1=[2*a for a in range(10)]
比如list,生成器,並不完全生成list的全部內容
如果列表元素可以按照某種演算法推算出來,這樣就不必建立完整的list
在Python中,這種一邊迴圈一邊計算的機制,稱為生成器:generator
生成器是一個特殊的程式,可以被用作控制迴圈的迭代行為,python中生成器是迭代器的一種,
使用yield返回值函式,每次呼叫yield會暫停
而可以使用next()函式和send()函式恢復生成器。
(1) generator的生成: 使用列表生成式--外面 [ ] 改為()
(2)只能使用一次,
可以使用 next(), 直至StopIteration
或者for x in generatorA
只能使用1次,前面顯示了,後面迴圈直接從未使用過的用起
(3) 當程式比較複雜難以用列表生成式的方式產生生成器時,使用yield函式:
>>> listA=[2*a for a in range(10)]
>>> listA
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> generatorA=(2*a for a in range(10))
>>> generatorA
<generator object <genexpr> at 0x0000000002FF82A0>
如何generator取值
>>> next(generatorA)
0
>>> next(generatorA)
2
>>> for x in generatorA:
x
4
6
8
10
12
14
16
18
>>>