問題描述
我想從符合條件的列表中獲取第一項(xiàng).重要的是,生成的方法不處理整個(gè)列表,這可能非常大.例如,下面的函數(shù)就足夠了:
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
這個(gè)函數(shù)可以這樣使用:
This function could be used something like this:
>>> first(range(10))
0
>>> first(range(10), lambda i: i > 3)
4
但是,我想不出一個(gè)好的內(nèi)置/單線讓我這樣做.如果不需要的話,我并不特別想復(fù)制這個(gè)功能.是否有內(nèi)置方法可以獲取第一個(gè)匹配條件的項(xiàng)目?
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:
如果您希望在未找到匹配元素的情況下引發(fā) 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)
請(qǐng)注意,在這種情況下,您需要在生成器表達(dá)式周圍添加一對(duì)額外的括號(hào) - 只要生成器表達(dá)式不是唯一的參數(shù),就需要它們.
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.
我看到大多數(shù)答案堅(jiān)決忽略next
內(nèi)置的,所以我假設(shè)出于某種神秘的原因,他們 100% 專注于 2.5 及更早版本 - 沒有提及 Python 版本問題(但我沒有在答案中看到 確實(shí)提到了內(nèi)置的next
,這就是為什么我認(rèn)為有必要自己提供一個(gè)答案——至少正確的版本"問題會(huì)以這種方式記錄下來;-).
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()
如果迭代器立即完成,則迭代器的方法會(huì)立即引發(fā) StopIteration
—— 即,對(duì)于您的用例,如果迭代器中沒有項(xiàng)目滿足條件.如果您不關(guān)心(即,您知道 必須 至少有一個(gè)令人滿意的項(xiàng)目),那么只需使用 .next()
(最好在 genexp 上,行next
在 Python 2.6 及更高版本中內(nèi)置).
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).
如果您確實(shí)在乎,最好按照您在 Q 中首先指出的那樣將東西包裝在一個(gè)函數(shù)中,雖然您提出的函數(shù)實(shí)現(xiàn)很好,但您也可以使用 itertools
,一個(gè) for...: break
循環(huán),或一個(gè) genexp,或一個(gè) try/except StopIteration
作為函數(shù)的主體,正如各種答案所建議的那樣.這些替代方案中的任何一個(gè)都沒有太多附加值,所以我會(huì)選擇您最初提出的極其簡(jiǎn)單的版本.
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.
這篇關(guān)于從匹配條件的迭代中獲取第一個(gè)項(xiàng)目的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!