2

I'm trying to loop over a list and save some elements to a new list: the ones that are at more than 50 greater than the previous value. My current code saves only the first value. I want [0, 76, 176, 262, 349].

list = [0, 76, 91, 99, 176, 192, 262, 290, 349]
new_list = []
for i in list:
    if ((i+1)-i) > 50:
        new_list.extend([i])
Prune
  • 76,765
  • 14
  • 60
  • 81
Jacob Quick
  • 43
  • 1
  • 4

5 Answers5

6

Solution

What I want is to save the values 0, 76, 176, 262, and 349.

So it sounds like you want to iterate over the list, and if the current element is greater than its preceding element by 50 then save it to the list and repeat. This solution assumes the original list is sorted. Let's turn this into some code.

lst = [0, 76, 91, 99, 176, 192, 262, 290, 349]
new_lst = []
for i, num in enumerate(lst):
    if i == 0 or num - lst[i-1] > 50:
        new_lst.append(num)

print(new_lst)
# [0, 76, 176, 262, 349]

The interesting part here is the conditional within the loop:

if i == 0 or num - lst[i-1] > 50:

The first part considers if we're at the first element, in which case I assume you want to add the element no matter what. Otherwise, get the difference between our current element and the previous element in the original list, and check if the difference is greater than 50. In both cases, we want to append the element to the list (hence the or).

Notes

  • You should avoid using list as a variable so you don't shadow the built-in Python type.
  • lst.extend([num]) is better written as lst.append(num).
  • enumerate(lst) allows you to easily get both the index and value of each element in a list (or any iterable).
foslock
  • 3,639
  • 2
  • 22
  • 26
  • 1
    creative solution, assuming ```list``` is sorted – RemedialBear Jun 29 '17 at 17:16
  • @RemedialBear Thanks for the reminder about the sorting :) – foslock Jun 29 '17 at 17:23
  • 1
    Thanks so much thats exactly what I needed – Jacob Quick Jun 29 '17 at 17:24
  • 1
    I don't think this works as specified. Consider the input list `[0, 76, 91, 99, 120, 150, 220]`. The correct output is `[0, 76, 220]`, but your solution ignores the chain 91-120 and include the value `150` in the output. `120` and `150` are not 50 apart, but this code compares only against the previously included value. – Prune Jun 29 '17 at 17:32
  • 1
    @Prune I would need clarification from OP, as the question could be interpreted both ways at this point. Either way, it'd be a simple change to the inner loop condition. – foslock Jun 29 '17 at 17:38
  • @Prune After re-reading the question a few times I realized you are right, I've edited my solution to properly answer the question :) – foslock Jun 29 '17 at 18:04
3

The statement if ((i+1)-i) > 50 will always evaluate to if (1 > 50) which is false. You're looking for the next element in list, but i is simply the value of the current element. Try something like the tee() function in the itertools library to get multiple values, or something like

list = [0, 76, 91, 99, 176, 192, 262, 290, 349]
new_list = []
for i in range(len(list)):
    print (i, list[i])
    if i == 0 or (list[i] - list[i-1]) > 50:
        new_list.append(list[i])

Keep in mind, I didn't add any checks for whether there is an i + 1 element, so you may need to do some error handling.

EDIT

This is my final edit. I would like to thank @Prune for enforcing standards :)

First, the code in PyCharm:

Code in PyCharm CE

Second, the console output:

Console output

RemedialBear
  • 644
  • 5
  • 15
  • The new list would contain duplicates, and consider using `append` instead of `extend` with `list[i]`, because `list[i]` is not a list. – Sam Chats Jun 29 '17 at 17:19
  • 1
    thanks @roganjosh, I made the edits. Kinda sucks when people downvote without mentioning what was wrong – RemedialBear Jun 29 '17 at 17:19
  • 1
    @RemedialBear _always_ worth checking it quickly for the 10 secs it takes. Makes it hard to beat the super-keen on getting the first answer, though, but you'd have found those errors yourself immediately I guess :) – roganjosh Jun 29 '17 at 17:21
  • 1
    This code has both a syntax error and a semantic error. Parentheses are unbalanced in the `if`, and you can't `extend` with a scalar. – Prune Jun 29 '17 at 17:27
  • I suspect this would miss `349`. – Sam Chats Jun 29 '17 at 17:47
  • @Prune okay, I think I've got it this time...hopefully I get a passing grade now – RemedialBear Jun 29 '17 at 18:06
0
for i in range(len(list)-1):
    if (list[i+1]-list[i]) > 50:
        new_list.append(list[i])
if list[-1] - new_list[-1] > 50:
    new_list.append(list[-1]) #for the last element of list

Of course, the code can be made better. But this should work.

Sam Chats
  • 2,271
  • 1
  • 12
  • 34
  • Why are you including a `set` operation? This indicates an untidiness within the loop, adding values twice. – Prune Jun 29 '17 at 17:34
  • @Prune I mentioned about making the code better. I just wanted it to be simple enough for the person who asked the problem. But since you mentioned it, I think I should do an edit :) – Sam Chats Jun 29 '17 at 17:40
0

You can put a condition inside a list comprehension. Also, do not give a variable the same name (list) as a built-in type.

my_list = [0, 76, 91, 99, 176, 192, 262, 290, 349]

# Start with the first element;
#   then grab each element more than 50 greater than the previous one.

new_list = [my_list[0]]
new_list.extend([my_list[i] for i in range(1, len(my_list))
                 if my_list[i] - my_list[i-1] > 50])
print(new_list)

Output:

[0, 76, 176, 262, 349]
foslock
  • 3,639
  • 2
  • 22
  • 26
Prune
  • 76,765
  • 14
  • 60
  • 81
0

my solution

l = [0, 76, 91, 99, 176, 192, 262, 290, 349]
o = list(l[0]) + [a for a, b in zip(l[1:], l[:-1]) if a - b - 50 > 0]

output: [0, 76, 176, 262, 349]

Alter
  • 3,332
  • 4
  • 31
  • 56