How to split list of tuples on condition?

I have list of tuples:

my_list = [(1,'a','b','c'), (2,'d','e','f'), (3,'g','h','i'), (1,'j','k','l'), (2,'m','n','o'), (1,'p','q','r'), (2,'s','t','u')]

I need to split it on sublists of tuples starting with a tuple where first item is '1'.

[(1,'a','b','c'), (2,'d','e','f'), (3,'g','h','i')]
[(1,'j','k','l'), (2,'m','n','o')]
[(1,'p','q','r'), (2,'s','t','u')]

Upvotes: 0

Views: 403

Answers (2)

Hans Musgrave
Hans Musgrave

Reputation: 7131

You're effectively computing some kind of a "groupwhile" function -- you want to split at every tuple you find starting in a 1. This looks an awful lot like itertools.groupby, and if we keep a tiny bit of global state (the one_count variable in our example) we can re-use the grouping/aggregation logic already built-in to the language to get your desired result.

import itertools

# The inner function is just so that one_count will be initialized only
# as many times as we want to call this rather than exactly once via
# some kind of global variable.
def gen_count():
    def _cnt(t, one_count=[0]):
        if t[0] == 1:
            one_count[0] += 1
        return one_count[0]
    return _cnt

result = [list(g[1]) for g in itertools.groupby(my_list, key=gen_count())]

A more traditional solution would be to iterate through your example and append intermediate outputs to a result set.

result = []
for i, *x in my_list:
    if i==1:
        result.append([(i, *x)])
    else:
        result[-1].append((i, *x))

Upvotes: 3

Mike67
Mike67

Reputation: 11342

Try this code. I assume the break is when the first character (1) is found again. I also assume the output is a list.

my_list = [(1,'a','b','c'), (2,'d','e','f'), (3,'g','h','i'), (1,'j','k','l'), (2,'m','n','o'), (1,'p','q','r'), (2,'s','t','u')]

ch = my_list[0][0]
all = []
st = 0
for i, t in enumerate(my_list):
    if t[0] == ch:
       if i != 0: 
           all.append(my_list[st:i])
           st = i
else:
   all.append(my_list[st:i])
   
print(all)

Output

[
[(1, 'a', 'b', 'c'), (2, 'd', 'e', 'f'), (3, 'g', 'h', 'i')], 
[(1, 'j', 'k', 'l'), (2, 'm', 'n', 'o')], 
[(1, 'p', 'q', 'r')]
]

Upvotes: -1

Related Questions