2012-03-26 73 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

相关问题