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
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]
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]))
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]
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]