我想知道Python内置函数中没有first(iterable)
的原因,有点类似于any(iterable)
和all(iterable)
(它可能藏在某个stdlib模块中,但我在itertools
中没有看到)。first
将执行短路发生器评估,以便避免不必要的(可能是无限数量的)操作;即
def identity(item):
return item
def first(iterable, predicate=identity):
for item in iterable:
if predicate(item):
return item
raise ValueError('No satisfactory value found')
这样你可以表达如下内容:
denominators = (2, 3, 4, 5)
lcd = first(i for i in itertools.count(1)
if all(i % denominators == 0 for denominator in denominators))
显然,在这种情况下不能执行list(generator)[0]
,因为生成器不会终止。
或者,如果要匹配一堆regex(当它们都具有相同的groupdict
接口时非常有用):
match = first(regex.match(big_text) for regex in regexes)
通过避免list(generator)[0]
和对正匹配进行短路,可以节省许多不必要的处理。
如果有迭代器,可以调用它的
next
方法。类似于:我最近问了一个similar question(它现在被标记为这个问题的副本)。我还担心的是,我希望只使用内置的来解决寻找生成器的第一个真实值的问题。我自己的解决办法是:
例如,查找第一个regexp匹配项(不是第一个匹配模式!)这看起来像这样:
它不会对谓词求值两次(如果只返回模式,则必须这样做),而且在理解中也不会使用类似于局部的hack。
但是它有两个嵌套的生成器,逻辑要求只使用一个。所以一个更好的解决方案是好的。
有一个Pypi package called “first”这样做:
下面是返回第一个奇数的方法,例如:
如果只想从迭代器返回第一个元素,而不管是否为true,请执行以下操作:
它是一个非常小的包:它只包含这个函数,它没有依赖项,它在Python2和3上工作。它是一个单独的文件,所以你甚至不需要安装它就可以使用它。
事实上,这里几乎是整个源代码(从2.0.1版开始,由Hynek Schlawack根据MIT许可证发布):
相关问题 更多 >
编程相关推荐