itertools.groupby
will group consecutive items that satisfy the key function. See the (key, group) pairs below. Notice at the end what happens to the adjacent even items:
>>> from itertools import groupby
>>> lst = [1, 2, 3, 4, 6, 8]
>>> grouped = [(k, list(g)) for k, g in groupby(lst, key=lambda x: x % 2)]
>>> grouped
[(1, [1]), (0, [2]), (1, [3]), (0, [4, 6, 8])]
Here are some ways to get groups of evens and odds:
>>> lst = [1, 2, 3, 4]
# OK, post-process groupby iterator
>>> grouped = [(k, list(g)) for k, g in groupby(lst, key=lambda x: x % 2)]
>>> evens = [x[1][0] for x in grouped if not x[0]]
>>> odds = [x[1][0] for x in grouped if x[0]]
>>> evens, odds
([2, 4], [1, 3])
# Better, pre-"sort"/rearrange iterable then groupby (see comments)
>>> key = lambda x: x % 2
>>> rearranged = sorted(lst, key=key)
>>> evens, odds = [(list(g)) for k, g in groupby(rearranged, key=key)]
>>> evens, odds
([2, 4], [1, 3])
# Even Better, simple list comprehensions
>>> evens, odds = [x for x in lst if not x % 2], [x for x in lst if x % 2]
>>> evens, odds
([2, 4], [1, 3])
See docs and this post for more on itertools.groupby
.
Alternatives
For complex groupings, you may map a function and collect values in a defaultdict
.
>>> import collections as ct
>>> def even_odd(elem):
... key = "odd" if elem % 2 else "even"
... return key, elem
>>> dd = ct.defaultdict(list)
>>> for k, v in map(even_odd, range(1, 5)):
... dd[k].append(v)
>>> dd
defaultdict(list, {'even': [2, 4], 'odd': [1, 3]})