ajsp
ajsp

Reputation: 2670

Split list of tuples where second elment is greater than threshold

I have a list of tuples that I need to split, where every second element in the tuple is greater than 1, into a "list of lists of tuples". From those lists of tuples I am trying to calculate the difference between the first element of the first tuple in the new list, and the first element of the last tuple in the new list. Sorry if that seems confusing.

Take the following as an example:

zp = [(1.31, 0), (1.32, 0),
      (1.33, 0), (1.34, 0),
      (1.35, 1), (1.36, 2),
      (1.37, 3), (1.37, 4),
      (1.39, 5), (1.38, 6),
      (1.40, 7), (1.41, 8),
      (1.42, 9), (1.43, 10),
      (1.44, 0), (1.45, 0),
      (1.46, 0), (1.47, 0),
      (1.48, 1), (1.49, 2),
      (1.50, 3), (1.51, 4),
      (1.52, 0), (1.53, 0),
      (1.54, 1), (1.55, 2),
      (1.56, 3), (1.57, 4),
      (1.48, 0), (1.59, 0),
      (1.60, 0), (1.61, 0),
      (1.62, 1), (1.63, 2),
      (1.64, 3), (1.65, 4),
      (1.66, 0), (1.67, 0),
      (1.68, 1), (1.69, 2),
      (1.70, 3), (1.71, 4)]

From here I enumerate all positions where the second element of the tuple is > 1, and get sequences of indexes for zp:

enums = [j for j, k in enumerate(zp) if not k[1] in (0,1)]

enums 
[5, 6, 7, 8, 9, 10, 11, 12, 13, 19, 20, 21, 25, 26, 27, 33, 34, 35, 39, 40, 41]

Here is where I start to suspect that I am taking a wrong turn as I have been going around in quite a few circles. For example, using for loops to get the slices for zp:

for k in range(1, len(enums)):
    if enums[k] - enums[k-1] > 1:
        print "index k-1", k-1, "end if seq: emum[k-1]", enums[k-1], " --", "index k", k, "start if next seq: emum[k-1]", enums[k]

And then from there, slicing zp with the altered enum indexes...so there has to be a better way right?

Any suggestions welcome.

*EDIT

Expected outcome:

[(1.36, 2),(1.37, 3), (1.37, 4),(1.39, 5), (1.38, 6),(1.40, 7), (1.41, 8),(1.42, 9), (1.43, 10)],
[(1.49, 2),(1.50, 3), (1.51, 4)], 
[(1.55, 2),(1.56, 3), (1.57, 4)],
[(1.63, 2),(1.64, 3), (1.65, 4)],
[(1.69, 2),(1.70, 3), (1.71, 4)]]

Upvotes: 1

Views: 1148

Answers (1)

Suever
Suever

Reputation: 65460

You can use itertools.groupby to group the results based on the condition that the second item of each tuple is > 1 (lambda x: x[1] > 1). This will return a group for each set of consecutive items for which that conditional has the same result (either True or False). We can then use a list comprehension to ignore the groups that were grouped because the conditional was False and convert the groups to a list where the conditional was True.

import itertools
A = [list(group) for val, group in itertools.groupby(zp, lambda x: x[1] > 1) if val]

# [[(1.36, 2), (1.37, 3), (1.37, 4), (1.39, 5), (1.38, 6), (1.4, 7), (1.41, 8), (1.42, 9), (1.43, 10)], 
#  [(1.49, 2), (1.5, 3), (1.51, 4)],
#  [(1.55, 2), (1.56, 3), (1.57, 4)], 
#  [(1.63, 2), (1.64, 3), (1.65, 4)], 
#  [(1.69, 2), (1.7, 3), (1.71, 4)]]

Upvotes: 1

Related Questions