On the surface, this might seem to be a duplicate of find first element in a sequence that matches a predicate but it is not.
I have a predicate function (function of one argument) that does some processing on the argument and returns a non-None value when the processing is said to "succeed". I want to use that function efficiently on a list or even some iterable but I do not want to iterate over all elements of the list or iterable, but just return the return value of the predicate function when that value is not None, and then stop executing the predicate on subsequent elements.
I was hoping there was something in itertools that would do this, but they all seem hardwired to return the element of the original items passed to the predicate, and instead I want the returned value.
I have a solution shown below, but is overly heavy code-wise. I'm
wanting something more elegant and that does not require the firstof
utility function coded there.
Note: Reading the entire file into a list of lines is actually necessary here, since I need the full contents in memory for other processing.
I'm using Python 2 here; I do not want to switch to Python 3 at this time but will want to avoid using syntax that is deprecated or missing in 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
Suppose I have /tmp/myfile
contain:
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
Running the above program on it yeilds:
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