練習使用標準模組itertools裡的chain,可以把數個可迭代者串連起來。
使用3.x版的函式print
from __future__ import print_function
匯入
from itertools import chain
手上有三個串列
a = [70, 81, 92]
b = ['hi', 'hello', 'aloha', 'ahoy']
c = [31.3, 32.5, 29.2, 28.5]
按照想要的順序,丟入chain,得到迭代器,
for e in chain(a, b, c):
print(e, ' ', end='')
輸出:70 81 92 hi hello aloha ahoy 31.3 32.5 29.2 28.5
自己實作
def my_chain(*iterables):
for it in iterables:
for e in it:
yield e
for e in my_chain(a, b, c):
print(e, ' ', end='')
輸出:同上
另外,如果你想丟進去的東西,會是動態產生、或是某種迭代器,那麼可使用chain.from_iterable。
底下這個函式,若傳入4,會依序回傳[0]、[0, 1]、[0, 1, 2]、[0, 1, 2, 3](不一定是串列,依Python版本而定)
def foo(x):
i = 1
while i <= x:
yield range(0, i)
i += 1
使用chain.from_iterable把它們串起來
for e in chain.from_iterable(foo(4)):
print(e, ' ', end='')
輸出:0 0 1 0 1 2 0 1 2 3
自己實作
def my_chain_from_iterable(iterables):
for it in iterables:
for e in it:
yield e
for e in my_chain_from_iterable(foo(4)):
print(e, ' ', end='')
輸出:同上
請問版主一下,我使用Python 3.6,去run您文章中的
ReplyDeletedef foo(x):
i = 1
while i <= x:
yield range(0, i)
i += 1
用for i in foo(4): print(i),去iterate後得到的是
range(0, 1)
range(0, 2)
range(0, 3)
range(0, 4)
除非把程式碼改成
def foo(x):
i = 1
while i <= x:
yield from range(0, i)
i += 1
才會在 for i in foo(4): print(i) iterate後得到
0
0
1
0
1
2
0
1
2
3
是需要改什麼東西嗎,還是執行環境上的差異呢
因為yield與yield from不一樣。
Delete呼叫range()、回傳的是個range物件。直接print,就印出range物件。
>>> r = range(0, 3)
>>> print(r)
range(0, 3)
用yield from的話,會從range物件(符合迭代協定)拿出一個個元素。
感謝說明!!
Delete