2012-03-26 157 views
205

找到/返回與某個標準匹配的第一個列表項目的最優雅和有效的方式是什麼?查找與標準匹配的第一個序列項目

例如,如果我有一個對象列表,並且想要獲得屬性爲obj.val==5的那些對象的第一個對象。我當然可以使用列表理解,但是會產生O(n),如果n很大,這是浪費。一旦達到標準,我也可以使用break的循環,但我認爲可能會有更多pythonic /優雅的解決方案。

+2

什麼,如果你想獲得的項目和指標? – 2016-07-10 20:03:46

+1

@CharlieParker,爲了獲得索引和項目,使用枚舉() - next((idx,obj)for idx,obj in enumerate(objs)if obj.val == 5) – 2016-12-13 09:01:40

回答

367

如果你沒有任何其他的索引或爲對象進行排序的信息,那麼你將不得不重複,直到發現某個對象:

next(obj for obj in objs if obj.val==5) 

然而,這是不是一個完整的列表理解得更快。比較這兩個:

[i for i in xrange(100000) if i == 1000][0] 

next(i for i in xrange(100000) if i == 1000) 

第一個需要5.75ms,第二個需要58.3μs(100倍,因爲迴路縮短了100倍)。

+93

'next'也提供'默認「參數,在沒有對象存在的情況下。例如。 '下一個((如果i> 600,我在範圍內(500),600)'將返回600. – Darthfett 2012-07-24 23:13:53

+22

Python [**'next()'**](http://docs.python.org/2 /library/functions.html#next) – 2013-10-19 04:29:38

+5

嗯,就是這樣,但我只是希望正確的答案看起來更酷。我們總是宣傳python的優雅。如果你希望它是健壯的,你應該提供'default'(例如'None') - 然後你不要忘記'如果不是唯一的參數',那麼必須將生成器表達式加括號......好吧,這會如何影響可讀性?例如。第一個非路徑參數:'next((如果不是os.path.exists(arg),那麼參數arg在sys.argv中),None)' - 不是很友好。 – 2016-03-18 11:38:01

2
a=[100,200,300,400,500] 
def search(b): 
try: 
    k=a.index(b) 
    return a[k] 
except ValueError: 
    return 'not found' 
print(search(500)) 

如果發現其他人,它會返回「未找到」它會返回對象

+0

這很好,但只有在條件是與列表項目的比較時纔有效。我正在尋找一種更通用的解決方案來處理更廣泛的選擇範圍 – Jonathan 2012-03-26 09:38:58

+0

但@Jonathan在你提到的問題中**有效的方式找到\返回第一個列表項**,因此上面的列表a = [100,200,300,400,500]可以包含任何對象的類型不只是數字。 – 2012-03-26 09:42:21

+1

,我用「......符合某個標準」來結束這句話,這與在平等或身份上匹配時不一樣:) 我認爲你的解決方案對於平等\身份私人案例 – Jonathan 2012-03-26 11:35:15

相關問題