0

I have a list that I want to make sublists from it based on the percentage change of the elements inside the list. For example:

list=[11.7, 8.5, 11.3, 11.2, 10.8, 1.05]
plist = [100.0 * e1 / e2 - 100 for e1, e2 in zip(list[1:], list)]

plist is:

[-27.350427350427353, 32.94117647058823, -0.8849557522123916, 
 -3.5714285714285694, -90.27777777777777]

Any consecutive element's percentage change > -5 will get grouped into a sublist like,

[11.7, [8.5, 11.3, 11.2, 10.8], 1.05]

Are there any other ways to get the desired output without using the long list comprehension method?

3
  • 3
    don't use list as variable name! Commented Nov 8, 2017 at 9:08
  • Thanks, I'll remember that. Commented Nov 8, 2017 at 9:17
  • 1
    This is unclear: "Any consecutive element's percentage change > -5 will get grouped into a sublist like, " Commented Nov 8, 2017 at 9:40

4 Answers 4

1

I didn't clearly get your criteria with the example of the expected output however. You may apply the following:

Values = [11.7, 8.5, 11.3, 11.2, 10.8, 1.05]

First you determine the positions of change in the list (The if condition here is my understanding of 5% change you might want to change this according to your needs)

ChangePosition = [ Ind+1 for Ind,Pair in enumerate(zip(Values,Values[1:]))
                    if ((Pair [0] - Pair [1]) / Pair [0] > -0.05) ] 

Then you add the beginning and the end of the possible positions.

ChangePosition = [0] + ChangePosition + [len(Values)]

Finally you slice the Values according to these positions:

GroupedValues = [ Values[Start:Finish] if (Finish-Start)> 1 else Values[Start]
for Start,Finish in zip(ChangePosition ,ChangePosition [1:])]
Sign up to request clarification or add additional context in comments.

Comments

1
l=[11.7, 8.5, 11.3, 11.2, 10.8, 1.05, 11.7, 8.5, 11.3, 11.2, 10.8, 1.05]
print(l)

ul=[l[0]]
l2=[]
i=0
flag = True
while i < len(l)-1:
    x = 100.0 * l[i+1] / l[i] - 100
    if x > (-5):
        if l[i] not in l2:
            l2.append(l[i])
        if l[i+1] not in l2:
            l2.append(l[i+1])
    else:
        l2=[]
        if i !=0: 
            ul.append(l[i+1])
    if l2:
        if l2 not in ul:
            ul.append(l2)
    i+=1
print(ul)

Output 1

[11.7, 8.5, 11.3, 11.2, 10.8, 1.05]
[11.7, [8.5, 11.3, 11.2, 10.8], 1.05]

Output 2

[11.7, 8.5, 11.3, 11.2, 10.8, 1.05, 11.7, 8.5, 11.3, 11.2, 10.8, 1.05]
[11.7, [8.5, 11.3, 11.2, 10.8], 1.05, [1.05, 11.7], 8.5, [8.5, 11.3, 11.2, 10.8], 1.05]

The items 8.5 and 1.05 are present in both lists; I think that's expected.

Additional details

0 11.7 -27.350427350427353
1 8.5 32.94117647058823
2 11.3 -0.8849557522123916
3 11.2 -3.5714285714285694
4 10.8 -90.27777777777777
5 1.05 1014.2857142857142
6 11.7 -27.350427350427353
7 8.5 32.94117647058823
8 11.3 -0.8849557522123916
9 11.2 -3.5714285714285694
10 10.8 -90.27777777777777

1 Comment

This will not work if multiple sublists are required
1

You will need to track whether or not a sublist is underway. Something like this will work:

values = [11.7, 8.5, 11.3, 11.2, 10.8, 1.05]  # 'list' is a bad name
grouped_values = [values[0]]
sublist = None
for x, y in zip(values[:-1], values[1:]):
    change = 100.0 * y / x - 100.0
    if change > -5:
        if sublist is None:
            sublist = []
        sublist.append(y)
    else:
        if sublist is not None:
            grouped_values.append(sublist)
            sublist = None
        grouped_values.append(y)
if sublist is not None:
    grouped_values.append(sublist)

Comments

0

starting from lxop 'answer' I made this, I believe, working code

the hint is fine but the only flag you need is whether sublist is empty or not if sublist != []

I did add [values[-1]/2] to values[1:] so the zip doesn't cut off the last element of values

Then the calculation with x = values[-1]/2 forces the last element of values (= y) into the else clause which does the right thing re the last element being in the last sublist or not

values = [11.7, 8.5, 11.3, 11.2, 10.8, 5, 1.05, 1.9, 1]

grouped_values, sublist = [], []

for x, y in zip(values[1:] + [values[-1]/2], values):

    if 100.0 * (x / y - 1) > -5:
        sublist.append(y)
    else:
        if sublist != []:
            sublist.append(y)
            grouped_values.append(sublist)
            sublist = []
        else:
            grouped_values.append(y)


grouped_values
Out[181]: [11.7, [8.5, 11.3, 11.2, 10.8], 5, [1.05, 1.9], 1]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.