3

I have a list = [1, 2, 3, 3, 6, 8, 8, 10, 2, 5, 7, 7] I am trying to use groupby to convert it into

1
2
3
3
6
8,8
10
2,
5
7,7

Basically, anything greater then 6, I like to group them, otherwise I want to keep them ungrouped. Any hint on how I can do this with itertool groupby

My code currently:

for key, group in it.groupby(numbers, lambda x: x):
   f = list(group)
   if len(f) == 1:
      split_list.append(group[0])
   else:
      if (f[0] > 6):  #filter condition x>6
         for num in f: 
            split_list.append(num + 100)
       else:
         for num in f:
            split_list.append(num)
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
Romeo
  • 147
  • 1
  • 3
  • 11

2 Answers2

5

You can use itertools.groupby to group all elements greater than 6 and with groups of length greater than 1. All other elements remain ungrouped.

If we want groups as standalone lists, we can use append. If we want groups flattened, we can use extend.

from itertools import groupby

lst = [1, 2, 3, 3, 6, 8, 8, 10, 2, 5, 7, 7]

result = []
for k, g in groupby(lst):
    group = list(g)

    if k > 6 and len(group) > 1:
        result.append(group)
    else:
        result.extend(group)

print(result)

Output:

[1, 2, 3, 3, 6, [8, 8], 10, 2, 5, [7, 7]]
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
1

You can use flatten() function shown below. This function is modified version from https://stackoverflow.com/a/40857703/501852

The function below is a generator object (python ver >= 3.8).

Added conditioning function as input parameter.

from typing import Iterable 

def flatten(items, cond_func=lambda x: True):
    """Yield items from any nested iterable"""
    for x in items:
        if isinstance(x, Iterable) \
                and not isinstance(x, (str, bytes)) \
                and cond_func(x):    # Conditioning function
            yield from flatten(x)
        else:
            yield x

Then you can use list comprehension variant:

res = flatten( [list(g) for k, g in groupby(lst)],
                cond_func = lambda x: x[0] <= 6 or len(x) == 1)
                 # Conditions to flatten

print(res)

And you can use generator variant:

res = flatten( (list(g) for k, g in groupby(lst)),
                cond_func = lambda x: x[0] <= 6 or len(x) == 1)
                 # Conditions to flatten

print(list(res))

Output is

[1, 2, 3, 3, 6, [8, 8], 10, 2, 5, [7, 7]]
Andrei Krivoshei
  • 715
  • 7
  • 16