2011-03-31 39 views
15

我可以在列表解析/發電機表達式中使用iffor作爲在列表理解或發電機使用,而表達式

list(i for i in range(100) if i*i < 30) 

我知道這是不是最有效的,但包涵的條件可能會更加這很複雜,這只是一個例子。然而,這仍然經過百次迭代和僅產生在第6的值有沒有辦法告訴發電機表達在哪裏停止像這樣的東西:

list(i for i in range(100) while i*i < 30) 

然而,while不產生理解表達式。所以,我的問題是,如何編寫一個帶停止條件的生成器表達式,以便它不會繼續計算,即使它不產生新值。

+1

請注意:你可以直接使用'[i for i in range(100)]' – Joril 2011-03-31 20:29:25

+0

生成一個列表。奇怪的是,有[PEP3142](https://www.python.org/dev/peps/ pep-3142 /)在詢問這個問題時打開。給出的用例幾乎就是這一個。 Guido在2013年5月加入了它 – 2015-08-28 07:12:23

回答

9

itertools(想到的takewhile())中的各種功能可以提供幫助。

20

由於takewhile()dropwhile()語法不是清晰的,這裏是你的問題的實際例子:

>>> [i for i in itertools.takewhile(lambda x: x*x<30, range(10))] 
[0, 1, 2, 3, 4, 5] 
>>> [i for i in itertools.dropwhile(lambda x: x*x<30, range(10))] 
[6, 7, 8, 9] 

要知道,itertools has questioned的作者是否棄用這些功能。

+0

如果這些功能被棄用,那麼配方會是什麼? – highBandWidth 2011-09-01 21:40:48

+0

只需查看[itertools.takewhile](http://docs.python.org/library/itertools.html#itertools.takewhile)和[itertools.dropwhile]的Python文檔(http://docs.python.org /library/itertools.html#itertools.dropwhile)。每個都有直接的Python等價物。 – dawg 2011-09-01 23:54:39

+6

不僅僅是'list(itertools.takewhile(lambda x:x * x <30,range(10)))'比這裏的理解更容易 – wim 2013-03-14 12:15:58