-3

I am trying to find the start and stop indices of chunks of positive numbers in a list.

cross = [7,5,8,0,0,0,0,2,5,8,0,0,0,0,8,7,9,3,0,0,0,3,2,1,4,5,0,0,0,7,5] 

For the given example input, the desired output is:

[(0, 2), (7, 9), (14, 17), (21, 25), (29, 30)]
Georgy
  • 12,464
  • 7
  • 65
  • 73
  • How about adapting answers to [other questions on SO](https://stackoverflow.com/questions/7270321/finding-the-index-of-elements-based-on-a-condition-using-python-list-comprehensi#7270932)? Please note that they discuss also "Why do you need the index?". – Mr. T Jan 03 '18 at 11:56

2 Answers2

2

How about using some flags to track where you are in the checking process and some variables to hold historical info?

This is not super elegant code but it is fairly simple to understand I think and fairly robust for the use case you gave.

My code

cross = [7,5,8,0,0,0,0,2,5,8,0,0,0,0,8,7,9,3,0,0,0,3,2,1,4,5,0,0,0,7,5] 
foundstart = False
foundend = False
startindex = 0
endindex = 0
for i in range(0, len(cross)):
    if cross[i] != 0:
        if not foundstart:
            foundstart = True
            startindex = i
    else:
        if foundstart:
            foundend = True
            endindex = i - 1

    if foundend:
        print(startindex, endindex)
        foundstart = False
        foundend = False
        startindex = 0
        endindex = 0

if foundstart:
    print(startindex, len(cross)-1)

Output

0 2
7 9
14 17
21 25
29 30
jwpfox
  • 5,124
  • 11
  • 45
  • 42
  • cross= [0,7,5,10,8,0,0,0,0,2,5,8,0] idx = 0 itr = range(0, len(cross)).__iter__() greater = [] for x in range(0, len(cross)): if cross[x] > 0: if(idx == 0): greater.append(x) print(x) idx+=1 elif(idx > 0 and cross[x] == 0): idx = 0 greater.append(x - 1) print(x - 1) – user9167921 Jan 03 '18 at 12:51
  • i tired the above code, but i'm unable to get the index of last values if not followed by 0 – user9167921 Jan 03 '18 at 12:52
0

A simpler approach would be to enumerate the values of the given list, and then group the index-value pairs by given condition with the help of itertools.groupby. From there getting the indices is trivial:

from itertools import groupby

cross = [7,5,8,0,0,0,0,2,5,8,0,0,0,0,8,7,9,3,0,0,0,3,2,1,4,5,0,0,0,7,5]
indexed_cross = enumerate(cross)  # will yield pairs (0, 7), (1, 5), (2, 8)...
key = lambda x: x[1] > 0  # will give True for pairs with positive second items
indices = []
for key, group in groupby(indexed_cross, key=key):
    if key:  # True for positive-values groups
        chunk = list(group)
        indices.append((chunk[0][0], chunk[-1][0]))  # extracting the indices
print(indices)
# [(0, 2), (7, 9), (14, 17), (21, 25), (29, 30)]

Alternatively, NumPy can be used for larger arrays:

import bumpy as np

cross = np.array(cross)
padded_values = np.r_[-cross[0], cross, -cross[-1]]  # accounting for the first and the last indices
indices = np.where(np.diff(padded_values > 0) != False)[0]
indices = indices.reshape(-1, 2)
indices[:, 1] -= 1
print(indices)
# [[ 0  2]
#  [ 7  9]
#  [14 17]
#  [21 25]
#  [29 30]]
Georgy
  • 12,464
  • 7
  • 65
  • 73