天天看點

Python3+疊代器與生成器

轉載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           

探尋有趣之事!