表面上看,这似乎是查找与谓词匹配的序列中的第一个元素的复制,但事实并非如此。
我有一个谓词函数(一个参数的函数),它对参数进行一些处理,并在处理被称为“成功”时返回一个非无值。我想有效地在列表上使用这个函数,甚至是一些可迭代的函数,但是我不想对列表中的所有元素进行迭代,而是在谓词函数的返回值不是None时返回它,然后停止对后续元素执行谓词。
我本来希望迭代工具中有一些东西可以做到这一点,但它们似乎都是硬连接起来的,可以返回传递给谓词的原始项的元素,相反,我需要返回的值。
下面显示了一个解决方案,但是代码太重了。我想要一些更优雅的东西,这不需要在那里编码firstof实用程序函数。
注意:在这里,将整个文件读入行列表实际上是必要的,因为我需要内存中的全部内容来进行其他处理。
我在这里使用Python 2;此时我不想切换到Python 3,但希望避免使用Python 3中不推荐或缺少的语法。
import re
def match_timestamp(line):
timestamp_re = r'\d+-\d+-\d+ \d+:\d+:\d+'
m = re.search(r'^TIMESTAMP (' + timestamp_re + ')', line)
if m:
return m.group(1)
return None
def firstof(pred, items):
"""Find result from the first call to pred of items.
Do not continue to evaluate items (short-circuiting)."""
for item in items:
tmp = pred(item)
if tmp:
return tmp
return None
log_file = "/tmp/myfile"
with open(log_file, "r") as f:
lines = f.readlines()
for line in lines:
print "line", line.rstrip()
timestamp = firstof(match_timestamp, lines)
print "** FOUND TIMESTAMP **", timestamp假设我有/tmp/myfile包含:
some number of lines here
some number of lines here
some number of lines here
TIMESTAMP 2017-05-09 21:24:52
some number of lines here
some number of lines here
some number of lines here在其上运行上述程序:
line some number of lines here
line some number of lines here
line some number of lines here
line TIMESTAMP 2017-05-09 21:24:52
line some number of lines here
line some number of lines here
line some number of lines here
** FOUND TIMESTAMP ** 2017-05-09 21:24:52发布于 2017-05-11 05:00:38
from itertools import imap, ifilter
timestamp = next(line for line in imap(match_timestamp, lines) if line)
# or
timestamp = next(ifilter(None, imap(match_timestamp, lines)))(我相信这就是在Python2中这样做的方法,在Python3中,您只需使用map。)
map函数位于您的行上,因此您可以获得转换值的懒惰迭代器,然后惰性地使用next和生成器表达式或ifilter从它获得下一个真实值。如果没有找到值,您可以选择是否让next引发StopIteration错误,或者为默认返回值提供第二个参数。
发布于 2017-05-11 04:29:10
编辑:您可以创建一个生成器并将其与next一起使用,直到找到时间戳为止。
with open(log_file, "r") as f:
lines = f.readlines()
for line in lines:
print "line", line.rstrip()
timestamp = None
generator = (match_timestamp(line) for line in lines)
while timestamp is None:
timestamp = next(generator)
print "** FOUND TIMESTAMP **", timestamphttps://stackoverflow.com/questions/43906476
复制相似问题