1

Given a list of numbers in ascending order. It is necessary to leave only elements to get such a list where the difference between the elements was greater or equal than a certain value (10 in my case).

Given:

list = [10,15,17,21,34,36,42,67,75,84,92,94,103,115]

Goal:

 list=[10,21,34,67,84,94,115]
Usman
  • 1,983
  • 15
  • 28
  • 2
    Welcome to SO. Read https://stackoverflow.com/help/how-to-ask – buran Jan 09 '20 at 13:28
  • Please show us your side of code that u tried with error/problem you get. – Rajan Lagah Jan 09 '20 at 13:29
  • ProTip: never use list name that matches the python object list. you will break everything :) – marxmacher Jan 09 '20 at 13:33
  • The question isn't very clear. Why, for example, do you keep `94` despite the fact that `94 - 92 = 2`, which isn't greater than or equal to `10`? – John Coleman Jan 09 '20 at 13:37
  • 1
    It isn't really a duplicate since the predicate is not independent of the final list. IIf you remove elements that differ from the previous elements by less than 10, the act of filtering would create new violations of the condition, requiring additional filtering (which answers the question I raised in the problem). Rather than thinking of it as a filtering problem, it is better to start by keeping the first element, and only keep additional elements if they differ from the last kept item by at least 10. – John Coleman Jan 09 '20 at 13:48
  • 1
    This is not a duplicate. The problem is comparing the elements inside the list, not filtering by attribute. – Mikhail Shumikhin Jan 09 '20 at 13:57

3 Answers3

2

you could use a while loop and a variable to track the current index you are currently looking at. So starting at index 1, check if the number at this index minus the number in the previous index is less than 10. If it is then delete this index but keep the index counter the same so we look at the next num that is now in this index. If the difference is 10 or more increase the index to look at the next num. I have an additional print line in the loop you can remove this is just to show the comparing.

nums = [10, 15, 17, 21, 34, 36, 42, 67, 75, 84, 92, 94, 103, 115]

index = 1
while index < len(nums):
    print(f"comparing {nums[index-1]} with {nums[index]} nums list {nums}")
    if nums[index] - nums[index - 1] < 10:
        del nums[index]
    else:
        index += 1

print(nums)

OUTPUT

comparing 10 with 15 nums list [10, 15, 17, 21, 34, 36, 42, 67, 75, 84, 92, 94, 103, 115]
comparing 10 with 17 nums list [10, 17, 21, 34, 36, 42, 67, 75, 84, 92, 94, 103, 115]
comparing 10 with 21 nums list [10, 21, 34, 36, 42, 67, 75, 84, 92, 94, 103, 115]
comparing 21 with 34 nums list [10, 21, 34, 36, 42, 67, 75, 84, 92, 94, 103, 115]
comparing 34 with 36 nums list [10, 21, 34, 36, 42, 67, 75, 84, 92, 94, 103, 115]
comparing 34 with 42 nums list [10, 21, 34, 42, 67, 75, 84, 92, 94, 103, 115]
comparing 34 with 67 nums list [10, 21, 34, 67, 75, 84, 92, 94, 103, 115]
comparing 67 with 75 nums list [10, 21, 34, 67, 75, 84, 92, 94, 103, 115]
comparing 67 with 84 nums list [10, 21, 34, 67, 84, 92, 94, 103, 115]
comparing 84 with 92 nums list [10, 21, 34, 67, 84, 92, 94, 103, 115]
comparing 84 with 94 nums list [10, 21, 34, 67, 84, 94, 103, 115]
comparing 94 with 103 nums list [10, 21, 34, 67, 84, 94, 103, 115]
comparing 94 with 115 nums list [10, 21, 34, 67, 84, 94, 115]
[10, 21, 34, 67, 84, 94, 115]
Chris Doyle
  • 10,703
  • 2
  • 23
  • 42
0

You could build up the list in a loop. Start with the first number in the list. Keep track of the last number chosen to be in the new list. Add an item to the new list only when it differs from the last number chosen by at least the target amount:

my_list = [10,15,17,21,34,36,42,67,75,84,92,94,103,115]

last_num = my_list[0]
new_list = [last_num]

for x in my_list[1:]:
    if x - last_num >= 10:
        new_list.append(x)
        last_num = x

print(new_list) #prints [10, 21, 34, 67, 84, 94, 115]
John Coleman
  • 51,337
  • 7
  • 54
  • 119
0

This problem can be solved fairly simply by iterating over your initial set of values, and adding them to your new list only when your difference of x condition is met.

Additionally, by putting this functionality into a function, you can get easily swap out the values or the minimum distance.

values = [10,15,17,21,34,36,42,67,75,84,92,94,103,115]

def foo(elements, distance):
  elements = sorted(elements) # sorting the user input
  new_elements = [elements[0]] # make a new list for output
  for element in elements[1:]: # Iterate over the remaining elements...
    if element - new_elements[-1] >= distance: 
      # this is the condition you described above
      new_elements.append(element)

  return new_elements

print(foo(values, 10))
# >>> [10, 21, 34, 67, 84, 94, 115]
print(foo(values, 5))
# >>> [10, 15, 21, 34, 42, 67, 75, 84, 92, 103, 115]

A few other notes here...

  • I sorted the array before I processed it. You may not want to do that for your particular application, but it seemed to make sense, since your sample data was already sorted. In the case that you don't want to sort the data before you build the list, you can remove the sorted on the line that I commented above.

  • I named the function foo because I was lazy and didn't want to think about the name. I highly recommend that you give it a more descriptive name.

David Culbreth
  • 2,610
  • 16
  • 26
  • you can get reid of the inital id in the function by just doing `new_elements = [elements[0]]` then when you iterate over the elements do `for element in sorted(elements[1:])` – Chris Doyle Jan 09 '20 at 17:00