4

I am trying to drop numbers located between consecutive numbers in list. Example:

Form

[1, 3, 5, 6, 7, 8, 9, 11, 12, 13, 18]

To

[1, 3, 5, 9, 11, 13, 18]

You'll see that [6, 7, 8] and [12] are dropped

pyaj
  • 545
  • 5
  • 15

4 Answers4

2

You can try itertools.groupby:

from itertools import groupby

lst = [1, 3, 5, 6, 7, 8, 9, 11, 12, 13, 18]

out = []
for _, g in groupby(enumerate(lst), lambda k: k[0] - k[1]):
    g = list(g)
    out.append(g[0][1])
    if len(g) > 1:
        out.append(g[-1][1])

print(out)

Prints:

[1, 3, 5, 9, 11, 13, 18]
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
1

I like to use zip to iterate over the list in parallel:

def drop_consecutive(a):
    if len(a)<3:
        yield from a
        raise StopIteration

    yield a[0]
    for (left, center, right) in zip(a[:-2], a[1:-1], a[2:]):
        if center==left+1 and right==center+1:
            pass # skip because they're consecutive
        else:
           yield center
    yield a[-1]


assert([1, 3, 5, 9, 11, 13, 18] == list(drop_consecutive( [1, 3, 5, 6, 7, 8, 9, 11, 12, 13, 18]))
Dave
  • 7,555
  • 8
  • 46
  • 88
1

Here is an approach that does not utilize any libraries:

def get_nums_with_dropped_internal_consecutive(nums):
    result = []
    if not nums:
        return result
    left = right = nums[0]
    for x in nums[1:]:
        if x - 1 != right:
            result.append(left) if left == right else result.extend([left, right])
            left = right = x
        else:
            right = x
    result.append(left) if left == right else result.extend([left, right])
    return result

nums = [1, 3, 5, 6, 7, 8, 9, 11, 12, 13, 18]
nums_with_dropped_internal_consecutive = get_nums_with_dropped_internal_consecutive(nums)
print(nums_with_dropped_internal_consecutive)

Output:

[1, 3, 5, 9, 11, 13, 18]
Sash Sinha
  • 18,743
  • 3
  • 23
  • 40
0

Check this out:

numbers = [2,3,5,6,7,8,11,12,13,15]
numbers_new = [numbers[0]]

for i in range(1, len(numbers)-1):
  if (numbers[i] == numbers[i-1]+1 and numbers[i] == numbers[i+1]-1):
    print(numbers[i], True)
  else:
    print(numbers[i], False)
    numbers_new.append(numbers[i])

numbers_new.append(numbers[-1])

numbers_new

Which will return the number and stating if it's located between consecutive numbers, as well as a new list containing only those numbers, not between consecutive numbers:

3 False
5 False
6 True
7 True
8 False
11 False
12 True
13 False
[2, 3, 5, 8, 11, 13, 15]

JhonnyB
  • 41
  • 4