找到与标准匹配的第一个序列项

Jon*_*han 280 python list

找到/返回符合特定标准的第一个列表项的最优雅和有效的方法是什么?

例如,如果我有一个对象列表,我想得到属性的第一个对象obj.val==5.我当然可以使用列表理解,但这会产生O(n),如果n很大,那就太浪费了.break一旦达到标准,我也可以使用循环,但我认为可能有更多的pythonic /优雅解决方案.

eum*_*iro 508

如果您没有任何其他索引或对象的已排序信息,则必须迭代直到找到这样的对象:

next(obj for obj in objs if obj.val==5)
Run Code Online (Sandbox Code Playgroud)

然而,这比完整列表理解更快.比较这两个:

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

next(i for i in xrange(100000) if i == 1000)
Run Code Online (Sandbox Code Playgroud)

第一个需要5.75ms,第二个需要58.3μs(因为环路短100倍,所以需要快100倍).

  • 在没有对象存在的情况下,`next`也提供了`default`参数.例如`next((i for i in range(500)if i> 600),600)`将返回600. (130认同)
  • Python [**`next()`**](http://docs.python.org/2/library/functions.html#next) (25认同)
  • 好吧,就是这样,但我只是期望正确的答案看起来更酷.我们总是宣传python是如此优雅.如果你想要它是健壮的,你应该提供`default`(例如`None`) - 然后你不要忘记`如果不是唯一的参数,那么生成器表达式必须用括号括起来......嗯,这是如何影响可读性的?例如,第一个非路径arugment:`next((如果不是os.path.exists(arg),则为sys.argv中的arg arg),无)` - 不太友好. (6认同)
  • 真正.如果你有足够的错误你可以总是`def first(items,pred):return next((i for i in items if pred(i)),None) (4认同)
  • 如果您也想查找项目和索引怎么办? (2认同)
  • 替代枚举版本:`next(((i, v) for (i, v) in enumerate(items) if pred(v)), None)` 工作原理完全相同,但显示来自 `enumerate` 的索引和值(是的,我们都知道它是如何工作的,但它并没有什么坏处)并让谓词处理该值而不对其进行索引。 (2认同)