Home > OS >  Return the index of the first element in the list from where incremental increase starts
Return the index of the first element in the list from where incremental increase starts

Time:11-27

Suppose I have a list like this, where numbers increase in different steps:

[ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]

I want to return the index for the first element in the list where the increase is incremental ( 1 step only). In this case, 23 is the first location from which point the increase becomes incremental, and its index would be 8, which is what I want as an output.

What would be an elegant simple way to achieve this? This is what I have tried:

>>> for (a,b) in zip(l, l[1:]):
...     if b-a == 1:
...             print(l.index(a))
...             break

UPDATE: In this particular setup, once the increase becomes incremental it will continue to stay that way. It is possible that the increase will never become incremental.

CodePudding user response:

Solution 1: operator

from operator import sub, indexOf

L = [ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]

print(indexOf(map(sub, L[1:], L), 1))
# prints 8

Raises ValueError: sequence.index(x): x not in sequence if difference 1 never occurs, so might want to use try/except for that.

Solution 2: bisect

This one only takes O(log n) time, using the monotonicity of incrementalness (as you commented "once the increase becomes incremental it will continue to stay that way").

from bisect import bisect

L = [ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]

class IsIncremental:
    def __getitem__(_, i):
        return L[i 1] - L[i] == 1

print(bisect(IsIncremental(), False, 0, len(L) - 1))
# prints 8

Prints len(L) - 1 if difference 1 never occurs.

Btw... readability

As PEP 8 says:

Never use the characters 'l' (lowercase letter el), [...] as single character variable names. In some fonts, these characters are indistinguishable from the numerals one and zero. When tempted to use 'l', use 'L' instead.

CodePudding user response:

Steps:

  1. Iterate over the array until the second last element.
  2. Check if next element value differs from current element value by exactly 1.
  3. Print the index and break the loop.

Code:

my_list = [0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
for i in range(len(my_list)-1):
    if my_list[i 1] - my_list[i] == 1:
        print(i)
        break

Result:

8

CodePudding user response:

Here is an iterative approach. We can loop over the list and take the following action at each index:

  • If the current value is one plus the previous, then don't move the incremental index
  • Otherwise, reset the incremental index to the current position

If we reach the end of the list and we have an incremental index which is earlier than the last position, then we have a potential match.

lst = [0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
idx = 0
for i in range(1, len(lst)):
    if lst[i] != lst[i-1]   1:
        idx = i

if idx < len(lst) - 1:
    print("Found index: "   str(idx)   ", value: "   str(lst[idx]))
else:
    print("No incremental index found")

This prints:

Found index: 8, value: 23

CodePudding user response:

Do a for each loop and check the previous value with the current. Once you reach a point where your current value is only 1 greater than the previous value, return the index of the previous value in your array:

myList = [ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
lastVal = -1000
for i in myList:
    if i - lastVal == 1:
        print(myList.index(lastVal)) #will print your desired value's index. If this is in a function, replace print with return
        break
    lastVal = i
if myList.index(lastVal) == len(myList) - 1:
    print("There is no incremental increase in your array")

(edited, replaced return with lastVal, fixed to print the index) Output:

8

CodePudding user response:

 My solution uses numpy and requires at least an element incremented by 1.

import numpy as np

l = [0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
l1 = l.copy()
l1.insert(0,0)
l.append(0)
l1, l = np.array(l1), np.array(l)

try:
    print(np.where(np.abs(l1-l) == 1)[0][0]-1)
except IndexError:
    print ("index 0 is out of bounds for axis 0 with size 0")
8

CodePudding user response:

Here is a way to do this using list comprehension

lst = [ 0,  4,  6,  8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
list2 = [i-1 for i,j in enumerate(lst) if j-lst[i-1]==1] 
if len(list2)>0:
    print(list2[0])
else:
    print('No one up number exists')

CodePudding user response:

Similar to the previous answer.

myList = [0, 4, 6, 8, 12, 15, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
l0 = 0 #suppose that the initial value is 0
for l1 in myList:
    increment = l1 - l0
    if increment == 1:
        print(myList.index(l0)) #if you want to get the second element, use l1 instead.
        break #if you want to get all the first elements that has 1 increment, remove break
    l0 = l1 #memorize l1
  • Related