计算python列表中标记之间的出现次数

use*_*025 5 python algorithm numpy

我有一个布尔(numpy)数组.而且我想知道Falses之间出现了多少次'True'.

例如,样本列表:

b_List = [T,T,T,F,F,F,F,T,T,T,F,F,T,F] 
Run Code Online (Sandbox Code Playgroud)

应该产生

ml = [3,3,1]
Run Code Online (Sandbox Code Playgroud)

我最初的尝试是尝试这个片段:

i = 0
ml = []
for el in b_List:
  if (b_List):
    i += 1
  ml.append(i)
  i = 0
Run Code Online (Sandbox Code Playgroud)

但是它会在b_List中为每个F添加以ml为单位的元素.

编辑

谢谢大家的答案.可悲的是,我可以'接受所有答案都是正确的.我接受了Akavall的答案,因为他提到了我最初的尝试(我知道我现在做错了什么),并且还对Mark和Ashwinis的帖子进行了比较.

请不要将接受的解决方案作为定义答案,因为其他建议都引入了同样有效的替代方法

Mar*_*son 5

itertools.groupby提供了一种简单的方法:

>>> import itertools
>>> T, F = True, False
>>> b_List = [T,T,T,F,F,F,F,T,T,T,F,F,T,F]
>>> [len(list(group)) for value, group in itertools.groupby(b_List) if value]
[3, 3, 1]
Run Code Online (Sandbox Code Playgroud)

  • 事实证明,这基本上是Alex Martelli在一个几乎重复的问题上给出的答案的重复.(除非Alex用`sum(group)`替换`len(list(group))`,这有点整洁.) (2认同)

Aka*_*all 2

您最初的尝试有一些问题:

i = 0
ml = []
for el in b_List:
    if (b_List): # b_list is a list and will evaluate to True
                 # unless you have an empty list, you want if (el)
        i += 1
    ml.append(i) # even if the above line was correct you still get here
                 # on every iteration, and you don't want that
    i = 0
Run Code Online (Sandbox Code Playgroud)

你可能想要这样的东西:

def count_Trues(b_list):
    i = 0
    ml = []
    prev = False
    for el in b_list:
        if el:
            i += 1
            prev = el
        else:
            if prev is not el:
                ml.append(i)
                i = 0
            prev = el
    if el:
        ml.append(i)
    return m
Run Code Online (Sandbox Code Playgroud)

结果:

>>> T, F = True, False
>>> b_List = [T,T,T,F,F,F,F,T,T,T,F,F,T,F] 
>>> count_Trues(b_List)
[3, 3, 1]
>>> b_List.extend([T,T])
>>> count_Trues(b_List)
[3, 3, 1, 2]
>>> b_List.extend([F])
>>> count_Trues(b_List)
[3, 3, 1, 2]
Run Code Online (Sandbox Code Playgroud)

该解决方案运行速度快得惊人:

In [5]: T, F = True, False

In [6]: b_List = [T,T,T,F,F,F,F,T,T,T,F,F,T,F] 

In [7]: new_b_List = b_List * 100

In [8]: import numpy as np

# Ashwini Chaudhary's Solution
In [9]: %timeit np.diff(np.insert(np.where(np.diff(new_b_List)==1)[0]+1, 0, 0))[::2]
1000 loops, best of 3: 299 us per loop

In [11]: %timeit count_Trues(new_b_List)
1000 loops, best of 3: 130 us per loop

In [12]: new_b_List = b_List * 1000

# Ashwini Chaudhary's Solution 
In [13]: %timeit np.diff(np.insert(np.where(np.diff(new_b_List)==1)[0]+1, 0, 0))[::2]
100 loops, best of 3: 2.25 ms per loop

In [14]: %timeit count_Trues(new_b_List)
100 loops, best of 3: 1.33 ms per loop
Run Code Online (Sandbox Code Playgroud)