轉載Python3 疊代器與生成器
疊代器
- 疊代是Python最強大的功能之一,是通路集合元素的一種方式。
- 疊代器是一個可以記住周遊的位置的對象。
- 疊代器對象從集合的第一個元素開始通路,直到所有的元素被通路完結束。疊代器隻能往前不會後退。
- 疊代器有兩個基本的方法:iter() 和 next()。
字元串,清單或元組對象都可用于建立疊代器:
l=[1,2,3,4]
it = iter(l) # 建立疊代器對象
print (next(it)) # 輸出疊代器的下一個元素
print (next(it))
1
2
l=[1,2,3,4]
it = iter(l) # 建立疊代器對象
for x in it:
print (x, end=" ")
1 2 3 4
也可以使用 next() 函數:
import sys # 引入 sys 子產品
li=[1,2,3,4]
it = iter(li) # 建立疊代器對象
while True:
try:
print (next(it))
except StopIteration:
sys.exit()
1
2
3
4
An exception has occurred, use %tb to see the full traceback.
SystemExit
C:\Users\xiner\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2870: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
生成器
在 Python 中,使用了
yield
的函數被稱為生成器(generator)。
跟普通函數不同的是,生成器是一個傳回疊代器的函數,隻能用于疊代操作,更簡單點了解生成器就是一個疊代器。
在調用生成器運作的過程中,每次遇到 yield 時函數會暫停并儲存目前所有的運作資訊,傳回yield的值。并在下一次執行 next()方法時從目前位置繼續運作。
import sys
def fibonacci(n): # 生成器函數 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一個疊代器,由生成器傳回生成
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
0 1 1 2 3 5 8 13 21 34 55
An exception has occurred, use %tb to see the full traceback.
SystemExit
C:\Users\xiner\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2870: UserWarning: To exit: use 'exit', 'quit', or Ctrl-D.
warn("To exit: use 'exit', 'quit', or Ctrl-D.", stacklevel=1)
Python yield 使用淺析
resversed(序列) 順序翻轉疊代
a=list('hello')
a
['h', 'e', 'l', 'l', 'o']
a1=reversed(a) #a1是一個疊代器
print(type(a))
print(type(a1))
<class 'list'>
<class 'list_reverseiterator'>
b=[1,2,3,4,5]
b1=reversed(b)
print(type(b))
print(type(b1))
<class 'list'>
<class 'list_reverseiterator'>
reversed((1,2,4,7,8))
<reversed at 0x2272e4a82e8>
a2=reversed(range(5))
list(a2)
[4, 3, 2, 1, 0]
zip(序列1,序列2) 并行疊代
l1=['a','b','c','d']
l2=[1,2,3,4]
list(zip(l1,l2))
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
l3=('a','b','c','d')
l4=[1,2,3,4]
list(zip(l1,l2))
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
l='hello'
s=range(len(l))
list(zip(l,s))
[('h', 0), ('e', 1), ('l', 2), ('l', 3), ('o', 4)]
l=dict(keys=l,values=s)
l
{'keys': 'hello', 'values': range(0, 5)}
s
range(0, 5)
list(zip(l,s))
[('keys', 0), ('values', 1)]
編号疊代
enumerate(序列):給序列打上編号
l=['1','b','h',8]
s=enumerate(l)
s
<enumerate at 0x2272dc60b88>
list(s)
[(0, '1'), (1, 'b'), (2, 'h'), (3, 8)]
循環控制語句
break & continue
- break結束目前循環,然後跳到循環後的下一條語句。
- continue提前結束目前這次循環,且繼續進行下一次循環。
a,b=0,1
while True:
a,b=b,a+b
if b>1000:
break
print(a)
987
# (數值之和小于100的行)的奇樹數值之和
m=[[12,13,20,9,30,7],[11,22,33,21,44],[30,32,25,66,1],[12,34,56,7]]
result=0
for l in m:
tmp=0
for n in l:
tmp+=n
if tmp>=100:
break
if tmp>=100:
continue
for n in l:
if n % 2==1:
result+=n
print(result)
29
else子句
flag
變量可用來訓示某一個特定事件是否已經發生,或某個特定狀态是否存在。
若需要在循環之後判斷該條件是否符合,則需要額外的辨別來記錄。
示例:
l=[2,4,8,0,10,12]
flag=False
for n in l:
if n%2==1:
flag=True
break
if not flag:
print('All num is even')
All num is even
與下面的
else子句
等價
l = [2, 4, 8, 0, 10, 12]
for n in l:
if n % 2 == 1:
flag = True
break
else:
print('All num is even')
All num is even
清單推導式
利用其他集合類對象(清單,元組,集合,字典,...)來建立新的清單的方法:
[2 * x for x in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
[2 * x for x in range(10) if x % 3 == 0]
[0, 6, 12, 18]
[(x, y) for x in range(2) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
字典推導式
a = ('a','b','c','df','gh')
b = ['sdd',1,2,3,4,5]
d = {a[i]:b[i] for i in range(len(a))}
d
{'a': 'sdd', 'b': 1, 'c': 2, 'df': 3, 'gh': 4}
元組推導式(疊代器)
a = (x**2 for x in range(10))
type(a)
generator
探尋有趣之事!