【问题标题】:Editing Subsequent Values in a List Using a For-Loop使用 For 循环编辑列表中的后续值
【发布时间】:2021-06-20 23:20:49
【问题描述】:

我有以下名为“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]

我想遍历列表,并且:

  1. 如果列表元素 = 1;
  2. 我想将列表中接下来的 5 个元素的值设置为 0;考虑等待期。

为此,我创建了以下辅助函数:

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

当我执行函数时,它只遍历列表的第一个元素并输出这个列表:

[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]

而不是这个列表:

[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]

这意味着我的函数只遍历第一组值,而不遍历列表的其余部分。

我哪里出错了?

【问题讨论】:

  • 第一个1.0不变,所以index = series_list.index(i)总是返回第一个1.0的索引。看看enumerate 一起迭代值和索引
  • 为什么预期的结果不是[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]

标签: python list for-loop iteration


【解决方案1】:

您的代码的错误确实是提到的index = series_list.index(i)@Adam.Er8。这是一种使用计数器查看剩余等待时间的方法。请注意,此方法会修改给定的列表,因此它会覆盖值。如果您需要之前和之后的值,则必须对其进行一些修改。

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)

【讨论】:

    【解决方案2】:
    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))
    

    【讨论】:

      【解决方案3】:

      正如评论中提到的,您总是使用 index() 找到相同的 first -1 值 ...您可以使用以下方法更改:

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

      输出:

      # 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
      

      此解决方案在列表中使用slice-assignment,这应该会导致替换成本更低,然后逐个进行替换 - 但更改的值总量仍然相同。

      【讨论】:

      • 您的结果与他们声明的预期结果不同。
      • @Manuel 你是对的,我的结果与他发布的不同。在他的原始数据中,他的索引 36(从 0 开始)是 -1,索引 37 是 1.0 - 在他的结果中 1.0 消失了 - 这就是我的结果不同的原因。
      • @Manuel 仍然感谢您指出这一点,只是人类,而是仔细检查然后发布错误的东西;)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-23
      • 2019-12-23
      • 2014-08-05
      • 2019-07-25
      相关资源
      最近更新 更多