Finding
the first occurrence in a collection of data is a common problem.
# Non Idiomatic found_line = None for line in logfile: if regex.match(line): found_line = line break return found_line
Compared to
# Idiomatic return next(line for line in logfile if regex.match(line), None)
or
# Idiomatic (thanks to Suresh V) from itertools import dropwhile return next(dropwhile(lambda x: not regex.match(x), logfile), None)
The idiomatic solution is not only more compact, but it reads better.
§
Idiomatic doesn't mean "pack as much into one expression as you can". I'd say instead that fixing your first example to avoid the unnecessary pieces:
ReplyDeletefor line in logfile:
....if regex.match(line):
........return line
return None
makes it just as nearly idiomatic as your second version.
I am not "packing as much into one expression as " I can. It is an often used and readable expression.
DeleteChanging the example to use returns presumes that we don't want to use the iterator after. It also seems unnecessary to extract this logic in it's own function unless there is a significant number of additional operations occurring in the function.
Evenn better, use itertools.dropwhile
ReplyDeleteUpdated to reflect a dropwhile version.
DeleteYour 'idiomatic' example does not work unless you wrap the generator expression in an extra set of parentheses.
ReplyDelete