1

I have an array of digits: array = [1.0, 1.0, 2.0, 4.0, 1.0]

I would like to create a function that extracts sequences of digits from the input array and appends to one of two lists depending on defined conditions being met

The first condition f specifies the number of places to look ahead from index i and check if a valid index exists. If true, append array[i] to list1. If false, append to list2.

I have implemented it as follows:

def somefunc(array, f):
    list1, list2 = [], []

    for i in range(len(array)):
        if i + f < len(array):
            list1.append(array[i])
        else:
            list2.append(array[i])
            
    return list1, list2

This functions correctly as follows:
somefunc(array,f=1) returns ([1.0, 1.0, 2.0, 4.0], [1.0])
somefunc(array,f=2) returns ([1.0, 1.0, 2.0], [4.0, 1.0])
somefunc(array,f=3) returns ([1.0, 1.0], [2.0, 4.0, 1.0])

However, I would like to add a second condition to this function, b, that specifies the window length for previous digits to be summed and then appended to the lists according to the f condition above.

The logic is this:

  • iterate through array and at each index i check if i+f is a valid index.
  • If true, append the sum of the previous b digits to list1
  • If false, append the sum of the previous b digits to list2
  • If the length of window b isn't possible (i.e. b=2 when i=0) continue to next index.

With both f and b conditions implemented. I would expect:
somefunc(array,f=1, b=1) returns ([1.0, 1.0, 2.0, 4.0], [1.0])
somefunc(array,f=1, b=2) returns ([2.0, 3.0, 6.0], [5.0])
somefunc(array,f=2, b=2) returns ([2.0, 3.0], [6.0, 5.0])

My first challenge is implementing the b condition. I cannot seem to figure out how. see edit below

I also wonder if there is a more efficient approach than the iterative method I have begun?

Given only the f condition, I know that the following functions correctly and would bypass the need for iteration:

def somefunc(array, f):
    return array[:-f], array[-f:]

However, I again don't know how to implement the b condition in this approach.


Edit

I have managed an iterative solution which implements the f and b conditions:

def somefunc(array, f, b):
    list1, list2 = [], []

    for i in range(len(array)):
        if i >= (b-1):
            if i + f < len(array):
                list1.append(sum(array[i+1-b: i+1]))
            else:
                list2.append(sum(array[i+1-b: i+1]))
            
    return list1, list2

However, the indexing syntax feels horrible and I so I am certain there must be a more elegant solution. Also, anything with improved runtime would really be preferable.

r0bt
  • 383
  • 3
  • 12

1 Answers1

0

I can see two minor improvements you could implement in your code:

def somefunc(array, f, b):
    list1, list2 = [], []
    size = len(array) # Will only measure the length of the array once
    
    for i in range(b-1, size): # By starting from b-1 you can remove an if statement
        if i + f < size: # We use the size here
            list1.append(sum(array[i+1-b: i+1]))
        else:
            list2.append(sum(array[i+1-b: i+1]))
            
    return list1, list2

Edit: An ever better solution would be to add the new digit and substract the last at each iteration. This way you don't need to redo the whole sum each iteration:

def somefunc(array, f, b):
    list1, list2 = [], []
    value = 0
    size = len(array)
    
    for i in range(b-1, size):
        if value != 0:
            value = value - array[i-b] + array[i] # Get the last value, add the value at index i and remove the value at index i-b
        else:
            value = sum(array[i+1-b: i+1])
        if i + f < size:
            list1.append(value)
        else:
            list2.append(value)
            
    return list1, list2
Mouettos
  • 23
  • 6