Reputation: 2670
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
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