Re: [問題] list的iterator應用問題

作者: max80713   2016-07-02 10:09:53
原po的程式碼可以說是generator版本的list comprehension,
什麼是list comprehension?
其實把原敘述的左右小括號改成中括號就是了,如下:
>>> test = [(x,y) for x in range(3) for y in range(x)]
會產生出類似的結果:
>>> test
[(1, 0), (2, 0), (2, 1)]
test會是一個list。這樣子的敘述其實等價於:
>>> test = []
>>> for x in range(3):
for y in range(x):
test.append((x,y))
(從上述程式碼原po大概就可以理解為什麼會有那樣的output了吧!)
list comprehension提供了一個更快速的方式建立起一個有規律的list,
x和y也會被清理掉而不會像下面那種方式依然存在。
但原po的程式碼則叫做generator expression:
>>> test = ((x,y) for x in range(3) for y in range(x))
得到的test會是一個generator,是一種iterator,
可以透過next()取得下一個值直到沒有東西,
>>> next(test)
(1, 0)
>>> next(test)
(2, 0)
>>> next(test)
(2, 1)
>>> next(test)
Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
next(test)
StopIteration
也可以像原po一樣透過for迴圈取值出來,
所以會得到類似list comprehension的結果。
那樣的敘述等價於:
>>> def test():
for x in range(3):
for y in range(x):
yield(x,y)
>>> test = test()
generator expression省去了建立generator function,實作iterator class的麻煩。
※ 引述《Neverfor (yorker)》之銘言:
: test=( (x, y) for x in range ( 3 ) for y in range (x) )
: for x,y in test:
: print(x,y)
: output:
: 1 0
: 2 0
: 2 1
: 不好意思 看了很久想不出來程式碼第一行跟結果的關係QQ
: 這種用法是什麼意思呢?
: 想問
: 1. (x,y)是否代表 輸出的iterator 1個elemeny 是 (x,y)
: 2.迴圈看不太懂意思
: 前面的for x 是否是後面y range的x
作者: sunshinehope (天使的眼淚)   2016-07-04 10:03:00
嗚嗚推
作者: ccvs (kisS x Sis)   2016-07-02 13:37:00
作者: Neverfor (八卦蟑螂)   2016-07-02 21:54:00
感謝大大用心回覆!!請問這種的類似用法,實際上好用嗎@@?
作者: max80713   2016-07-02 22:19:00
generator expression好用的地方在於短短的一行程式碼就可以做出你想要的generator;另外它會在需要用到的時候才分配一塊記憶體給下一個值,不像list comprehension產出越長的list,就會佔據越大的記憶體空間。
作者: Sunal (SSSSSSSSSSSSSSSSSSSSSSS)   2016-07-02 22:37:00
當list超大的時候就很好用了
作者: Neverfor (八卦蟑螂)   2016-07-03 03:40:00
謝謝
作者: Yshuan (倚絃)   2016-07-03 04:18:00
推講解
作者: enjoyloli (M)   2016-07-03 14:46:00
所以是處理超大List用小刮號,一般情況用中掛號?
作者: max80713   2016-07-03 15:42:00
端看需求而定:如果你想call一些list function或是重複使用這些值那建議把它們存成list;如果只是要掃過所有值一次,或是個數實在太多就用generator:)
作者: yougigun   2016-07-04 00:04:00
長知識!

Links booklink

Contact Us: admin [ a t ] ucptt.com