2

I have the following list named "test_list":

test_list = [1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 
 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0,
-1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 
-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 
-1.0, -1.0, -1.0, -1.0, 1.0]

I would like to iterate through the list, and:

  1. If a list element = 1;
  2. I would like to set the value of the next 5 elements in the list to 0; to factor-in a waiting period.

To do this I created the following helper function:

def adjust_for_wait_period(series_list, wait_period=5):
    
    for i in series_list:
        if i == 1:
            index = series_list.index(i)
            wait_period_list = list(range(1, (wait_period + 1)))
            for wait in wait_period_list:
                try:
                    series_list[index + wait] = 0
                except Exception as e:
                    pass
                
    return series_list

When I execute the function, it only iterates through the first elements of the list and outputs this list:

[1.0, 0, 0, 0, 0, 0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 
 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 
-1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
-1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 
-1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0]

Instead of this list:

[1.0, 0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 0, -1.0, 
 1.0, 0, 0, 0, 0, 0, -1.0, 1.0, 0, 0, 0, 
 0, 0, -1.0, -1.0, -1.0, -1.0, 1.0, 0, 0, 0, 0, 
 0, -1.0, 0, 0, 0, 0, 0, 1.0, 0, 0, 0, 
 0, 0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, 1.0]

This means that my function is only iterating through the first bunch of values and not iterating through the rest of the list.

Where could I be going wrong?

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
john_mon
  • 487
  • 1
  • 3
  • 13
  • 1
    the first `1.0` is unchanged, so `index = series_list.index(i)` always returns the index of the first 1.0. take a look at `enumerate` to iterate values and indexes together – Adam.Er8 Mar 24 '21 at 09:09
  • Why is the expected result not `[1.0, 0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, -1.0, -1.0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, 1.0]`? – Manuel Mar 24 '21 at 09:27

3 Answers3

1

The error with your code is indeed the index = series_list.index(i) @Adam.Er8 mentioned. Here is a method that uses a counter to see how much of the waiting period is left. Note that this method modifies the list given, so it overwrites values. If you need both the before and after values, you'll have to modify it a bit.

def adjust_for_wait_period(series_list, waiting_period=5):
    waiting_period_left = 0
    for i in range(len(series_list)):
        if waiting_period_left > 0:
            series_list[i] = 0.0
            waiting_period_left -= 1
        else:
            if series_list[i] == 1.0:   
                waiting_period_left = waiting_period

test_list = [1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 
 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0,
-1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 
-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 
-1.0, -1.0, -1.0, -1.0, 1.0]

adjust_for_wait_period(test_list)

print(test_list)
Lourens
  • 104
  • 1
  • 11
1

As mentioned in the comment, you always find the same first -1 value using index() ... you can change this by using:

test_list = [1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,
            1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0,
            -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0,
            -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0,
            -1.0, -1.0, 1.0]

def adjust_for_wait_period(series_list, wait_period=5):
  # changing the iterating list is fine because we do not lengthen/shorten it.
  # if you change the list-length by removing/adding elements you shoud enumerate
  # over a copy of it!
  for idx, value in enumerate(series_list):
    if value == 1.0:  # float equality tests are error prone, should be fine here
        # slice assignment: replaces exact amount of items needed even if < wait_period
        l[idx+1:idx+1+wait_period] = [0 for _ in range(len(l[idx+1:idx+1+wait_period]))] 
  return l
    
print(test_list, len(test_list))
tl = adjust_for_wait_period(test_list)
print(tl, len(tl))

Output:

# input
[1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 
 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 
 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 
 -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0] 57

# output
[1.0, 0, 0, 0, 0, 0, 1.0, 0, 0, 0, 0, 0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, 1.0, 0, 0, 
 0, 0, 0, -1.0, -1.0, -1.0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, 
-1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 0, 0, 0, 0, 0, -1.0, 1.0] 57

This solution uses slice-assignment on the list wich should lead to less costly replacing then doing it on a 1-by-1 basis - the total amount of values changed is still the same though.

Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • Your result differs from their stated expected result. – Manuel Mar 24 '21 at 09:29
  • @Manuel You are correct, my result differs from what he posted. In his original data the index 36 (0-based) of his is a -1, index 37 a 1.0 - in his result the 1.0 vanished - that is why my result differs. – Patrick Artner Mar 24 '21 at 09:38
  • @Manuel still thanks for pointing it out, just human and rather doublecheck then post a wrong thing ;) – Patrick Artner Mar 24 '21 at 09:43
1
def adjust_for_wait_period(series_list, wait_period=5):
    for idx, item in enumerate(series_list):
        if item == 1:
            for offset in range(wait_period):
                try:
                    series_list[idx + offset + 1] = 0
                except Exception as e:
                    pass
                
    return series_list

test_list = [1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 
 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0,
-1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 
-1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 
-1.0, -1.0, -1.0, -1.0, 1.0]

print(adjust_for_wait_period(test_list))
AcK
  • 2,063
  • 2
  • 20
  • 27