問題描述
我想從符合條件的列表中獲取第一項.重要的是,生成的方法不處理整個列表,這可能非常大.例如,下面的函數就足夠了:
I would like to get the first item from a list matching a condition. It's important that the resulting method not process the entire list, which could be quite large. For example, the following function is adequate:
def first(the_iterable, condition = lambda x: True):
for i in the_iterable:
if condition(i):
return i
這個函數可以這樣使用:
This function could be used something like this:
>>> first(range(10))
0
>>> first(range(10), lambda i: i > 3)
4
但是,我想不出一個好的內置/單線讓我這樣做.如果不需要的話,我并不特別想復制這個功能.是否有內置方法可以獲取第一個匹配條件的項目?
However, I can't think of a good built-in / one-liner to let me do this. I don't particularly want to copy this function around if I don't have to. Is there a built-in way to get the first item matching a condition?
推薦答案
在 Python 2.6+ 和 Python 3 中:
In Python 2.6+ and Python 3:
如果您希望在未找到匹配元素的情況下引發 StopIteration
:
If you want StopIteration
to be raised if no matching element is found:
next(x for x in the_iterable if x > 3)
如果您希望返回 default_value
(例如 None
):
If you want default_value
(e.g. None
) to be returned instead:
next((x for x in the_iterable if x > 3), default_value)
請注意,在這種情況下,您需要在生成器表達式周圍添加一對額外的括號 - 只要生成器表達式不是唯一的參數,就需要它們.
Note that you need an extra pair of parentheses around the generator expression in this case ? they are needed whenever the generator expression isn't the only argument.
我看到大多數答案堅決忽略next
內置的,所以我假設出于某種神秘的原因,他們 100% 專注于 2.5 及更早版本 - 沒有提及 Python 版本問題(但我沒有在答案中看到 確實提到了內置的next
,這就是為什么我認為有必要自己提供一個答案——至少正確的版本"問題會以這種方式記錄下來;-).
I see most answers resolutely ignore the next
built-in and so I assume that for some mysterious reason they're 100% focused on versions 2.5 and older -- without mentioning the Python-version issue (but then I don't see that mention in the answers that do mention the next
built-in, which is why I thought it necessary to provide an answer myself -- at least the "correct version" issue gets on record this way;-).
在 2.5 中,.next()
如果迭代器立即完成,則迭代器的方法會立即引發 StopIteration
—— 即,對于您的用例,如果迭代器中沒有項目滿足條件.如果您不關心(即,您知道 必須 至少有一個令人滿意的項目),那么只需使用 .next()
(最好在 genexp 上,行next
在 Python 2.6 及更高版本中內置).
In 2.5, the .next()
method of iterators immediately raises StopIteration
if the iterator immediately finishes -- i.e., for your use case, if no item in the iterable satisfies the condition. If you don't care (i.e., you know there must be at least one satisfactory item) then just use .next()
(best on a genexp, line for the next
built-in in Python 2.6 and better).
如果您確實在乎,最好按照您在 Q 中首先指出的那樣將東西包裝在一個函數中,雖然您提出的函數實現很好,但您也可以使用 itertools
,一個 for...: break
循環,或一個 genexp,或一個 try/except StopIteration
作為函數的主體,正如各種答案所建議的那樣.這些替代方案中的任何一個都沒有太多附加值,所以我會選擇您最初提出的極其簡單的版本.
If you do care, wrapping things in a function as you had first indicated in your Q seems best, and while the function implementation you proposed is just fine, you could alternatively use itertools
, a for...: break
loop, or a genexp, or a try/except StopIteration
as the function's body, as various answers suggested. There's not much added value in any of these alternatives so I'd go for the starkly-simple version you first proposed.
這篇關于從匹配條件的迭代中獲取第一個項目的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!