【问题标题】:How to find the index where values in a list, increase value?如何找到列表中值的索引,增加值?
【发布时间】:2020-09-28 15:24:48
【问题描述】:

我有一个看起来像这样的列表:

mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]

当元素从0 更改为1(而不是从1 更改为0)时,我需要附加到一个列表中。

我已尝试执行以下操作,但当它从 1 更改为 0 时也会注册。

i = 0 
while i != len(mot)-1:
    if mot[i] != mot[i+1]:
        mot_daily_index.append(i)
    i += 1

还有,但不是那么重要,是否有更简洁的实现方式?

【问题讨论】:

    标签: python list indexing


    【解决方案1】:

    以下是您可以通过列表理解来做到这一点的方法:

    mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]
    mot_daily_index = [i for i,m in enumerate(mot) if i and m and not mot[i-1]]
    print(mot_daily_index)
    

    输出:

    [7, 24]
    

    解释:

    • list(enumerate([7,5,9,3])) 将返回[(0, 7), (1, 5), (2, 9), (3, 3)],因此i for i, m in enumerate 中的i 是该迭代期间m 的索引。

    【讨论】:

      【解决方案2】:

      使用带有过滤器的列表推导来获取索引:

      mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]
      
      idx = [i for i,v in enumerate(mot) if i and v > mot[i-1]]
      print(idx)
      

      输出:

      [7, 24]
      

      【讨论】:

      • i,v in enumerate(mot[1:]) if v > mot[i]
      【解决方案3】:

      你可以使用

      lst = [0, 0, 0, 1, 1, 1, 0, 1]
      #      0  1  2  3  4  5  6  7
      
      for index, (x, y) in enumerate(zip(lst, lst[1:])):
          if x == 0 and y == 1:
              print("Changed from 0 to 1 at", index)
      

      产量

      Changed from 0 to 1 at 2
      Changed from 0 to 1 at 6
      

      【讨论】:

      • if not x and y: 更pythonic。
      • 这也是我写它的大致方式!上面的其他答案中似乎缺少zip
      【解决方案4】:

      这是一个使用itertools.groupby 将列表分组为 0 和 1 的解决方案:

      from itertools import groupby
      
      mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]
      
      mot_daily_index = []
      l = 0
      for s, g in groupby(mot):
          if s == 1:
              mot_daily_index.append(l)
          l += len(list(g))
      
      print(mot_daily_index)
      

      输出:

      [7, 24]
      

      【讨论】:

        【解决方案5】:
        mot = [0,0,0,0,1,0,1,0,1,1,1,0,1,1,1,0,0,0,0]
        mot_daily_index = [] # the required list
        for i in range(len(a)-1):
            if a[i]==0 and a[i+1]==1:
                ind.append(i)
        

        只要第 i 个元素与第 (i+1) 个元素不同,您的代码就会添加索引

        【讨论】:

          【解决方案6】:
          • 对于 3M 元素容器,此答案比接受的答案快67.2 times
          • 这可以使用numpy 来完成,方法是将list 转换为numpy.array
          • 他的答案代码是对Find index where elements change value numpy 代码的修改。
            • 该问题需要所有转换 v[:-1] != v[1:],而不仅仅是小到大的转换,v[:-1] < v[1:],在这个问题中。
          • 创建一个布尔数组,将数组与自身进行比较,并移动一位。
          • 使用np.where 返回True 的索引
            • 这会找到更改前的索引,因为数组被移位进行比较,所以使用+1得到正确的值。
          import numpy as np
          
          v = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0]
          
          # convert to array
          v = np.array(v)
          
          # create a Boolean array
          map = v[:-1] < v[1:]
          
          # return the indices
          idx = np.where(map)[0] + 1
          
          print(idx)
          [out]:
          array([ 7, 24], dtype=int64)
          

          %timeit

          # v is 3M elements
          v = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0] * 100000
          
          # accepted answer
          %timeit [i for i,m in enumerate(v) if i and m and not v[i-1]]
          [out]:
          336 ms ± 14 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
          
          # this answer
          v = np.array(v)
          %timeit np.where(v[:-1] < v[1:])[0] + 1
          [out]:
          5.03 ms ± 85.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
          

          【讨论】:

            【解决方案7】:

            一个使用zip的单行器:

            mot = [0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0]
            
            [i+1 for i,m in enumerate(zip(mot[:-1],mot[1:])) if m[0]<m[1]]
            
            # [7, 24]
            

            【讨论】:

              【解决方案8】:

              另一个列表理解:

              mot = [0,1,1,1,1,0,0,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0]
              
              change_mot = [index+1 for index, value in enumerate(zip(mot[:-1], mot[1:], )) if value[1] - value[0] == 1]
              

              产量

              [1, 8, 11, 15]
              

              仅当增量 = 1 时才会获取增量并记录索引。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2023-01-21
                • 2022-12-10
                • 2020-05-20
                • 1970-01-01
                • 2014-04-19
                • 1970-01-01
                • 2018-05-07
                相关资源
                最近更新 更多