Suppose a generator yields the below tuples one by one (from left to right)
(1, 2, 3), (2, 5, 6), (3, 7, 10), (4, 5, 11), (3, 5, 15), (4, 5, 9), (4, 6, 12)
...
and suppose I'd like to iterate as long as the predicate is true. Let that predicate be sum(yielded_value) < 20
. Then the iterator will stop by (3, 5, 15)
. I can do it with, say:
list(itertools.takewhile(lambda x: sum(x) < 20, some_generator()))
Question, how do I write a similar expression with two predicates? Suppose I want:
list(itertools.takewhile(lambda x: sum(x) < 20 and first_value_of_tuple > 3, some_generator()))
(which, in this case, stop by (4, 6, 12)
.)
You can access to elements of each tuple with index.
list(itertools.takewhile(lambda x: sum(x) < 20 and x[0] > 3, some_generator()))
Since everything in itertools
is lazily iterated, and you are using and
for two predicates, you can simply use two takewhile
iterators. Sometimes I find this more readable than putting both predicates in a single predicate function or lambda:
lessthan20 = itertools.takewhile(lambda x: sum(x) < 20, some_generator())
greaterthan3 = itertools.takewhile(lambda x: x[0] > 3, lessthan20)
list(greaterthan3)
It also makes it so that you don't have a single huge one liner if you need to add even more predicates in the future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With