2012-01-02 36 views
4

可能重複:
Is it Pythonic to use list comprehensions for just side effects?
proper use of list comprehensions - python列表理解等同不會產生一次性列表

Python有有用的和優雅的list comprehension語法。然而,AFAIK它總是產生一個列表。有時我覺得使用列表理解只是它的緊湊性的衝動和優雅,而無需在結果列表:

[some_func(x) for x in some_list if x>5] 

some_func()可以返回一些東西,我不需要,它可能不會在所有返回任何東西。我嘗試了生成器語法:

(some_func(x) for x in some_list if x>5) 

但是正如您可能會猜到的那樣,它不會重複執行some_list。它這樣做只能在一定的語境:

other_func(some_func(x) for x in some_list if x>5) 

所以...有沒有語法我失蹤得到這個工作,或者我應該一直回落到3條線?

for x in some_list: 
    if x>5: 
     some_func(x) 
+2

在這裏有一個合法和獨特的問題,「如何在不創建丟棄列表的情況下運行迭代器來完成」。 – 2012-01-02 07:14:28

+0

@RaymondHettinger是對的,我正在尋找一個構造的替代品,而不知道它的名字或者它是否存在。這與其他兩個鏈接的問題完全不同 – Jonathan 2012-01-02 07:40:56

+0

@ IgnacioVazquez-Abrams,@ delnan - 我也改變了問題的名稱來反映這個 – Jonathan 2012-01-02 07:47:14

回答

10

我不要現在如果你會發現它優雅,但有一個consume recipe in the itertools docs這是非常快,將運行一個迭代完成,而且沒有建築了一個清單:

>>> consume(some_func(x) for x in some_list if x>5) 
+0

我從未想到你能夠創建一個零長度的'deque'或者甚至是如果可以的話,那對任何事情都是有用的。 – kindall 2012-01-09 17:15:18

2

使用一個genex來獲得適當的值來迭代。

for i in (x for x in some_list if x > 5): 
    some_func(i) 
+0

@RaymondHettinger - 我不同意這很糟糕(事實上:+1)。我相反​​地發現它非常pythonic,因爲它使用'for'循環和一個生成器來表達它們的意思,以一種簡潔明瞭的方式...謹慎地闡明你爲什麼不喜歡它? – mac 2012-01-02 07:31:26

2

如果some_func()不返回值(即返回None):

any(some_func(x) for x in some_list if x > 5) 

是一種可能性。

否則,你可以這樣做:

any(some_func(x) and False for x in some_list if x > 5) 

或許更可讀的(考慮到匹配的all的純英文的意思)是:

all(some_func(x) or True for x in some_list if x > 5) 

我喜歡consume配方林峯發現但更好的是,因爲它不會迫使你讓發電機返回一些特殊的價值,以保證它完全消耗,並且啓動會更快。

0

說實話,在我的代碼,我更喜歡使用三線的表情,但我認爲你正在尋找一個班輪可能是這一個:

for x in some_list: func(x) if x>5 else None 

注:我嘗試使用pass,而不是None,我雖然看起來會好一點,但會引發SyntaxError異常。

+1

您只能返回對象(如'42'或'None'),而不是語句(如'pass','print'或'raise')。 – mac 2012-01-02 07:54:13