I have seen a pattern repeated a couple times in my team's code, it looks like this
numbers = [1, 2, 3, 4]
even_numbers = [n for n in numbers if n % 2 == 0]
odd_numbers = [n for n in numbers if n % 2 != 0]
I was wondering if there is a function somewhere (I have looked around but haven't been able to find it) that would do something like this
numbers = [1, 2, 3, 4]
even_numbers, odd_numbers = fork(numbers, lambda x: x % 2 == 0)
So, this function I am looking for, would receive an iterable and a function, and return two lists, one would be the values that match a provided condition, and the other would be the ones that didn't.
Is there something around python's standard library that achieves this?
list() takes any iterable and produces a new list from it, so we can use this to copy list1 , thus creating two lists that are exactly the same.
The naive way to split a list is using the for loop with help of range() function. The range function would read range(0, 10, 2) , meaning we would loop over the items 0,2,4,6,8 . We then index our list from i:i+chunk_size , meaning the first loop would be 0:2 , then 2:4 , and so on.
I usually call this sift
, but partition
is fine too.
Another, itertools-less implementation might be
def sift(iterable, predicate):
t = []
f = []
for value in iterable:
(t if predicate(value) else f).append(value)
return (t, f)
even, odd = sift([1, 2, 3, 4, 5], lambda x: x % 2 == 0)
EDIT: for a slightly more complex implementation that is about 30% faster (on my Python installation anyway):
def sift2(iterable, predicate):
t = []
f = []
ta = t.append
fa = f.append
for value in iterable:
(ta if predicate(value) else fa)(value)
return (t, f)
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