简体   繁体   中英

Editing Subsequent Values in a List Using a For-Loop

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?

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)

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM