查找元素是否在python列表中连续出现n次

时间:2014-10-16 15:38:17

标签: python list

myList = [True, True, False, False, True, False, True, False, False]

我想找到True是否连续出现3次。

我可以通过以下方式找到它:

for x0, x1, x2 in zip(myList, myList[1:], myList[2:]):
    if x0 == True and x1 == True and x2 == True:
        print True

有更好的方法吗?

6 个答案:

答案 0 :(得分:5)

使用itertools.groupby()对元素进行分组,然后对每个组进行计数。如果找到匹配项,使用any() function可以提前退出循环:

from itertools import groupby, islice

print any(sum(1 for _ in islice(g, 3)) == 3 for k, g in groupby(myList) if k)

if k过滤群组仅计算True值组。

itertools.islice() function确保我们只查看组的前3个元素,并忽略该组的其余部分。这样,您就可以避免计算下一个很多True值,以确定您至少找到了3个。

演示:

>>> from itertools import groupby, islice
>>> myList = [True, True, False, False, True, False, True, False, False]
>>> [sum(1 for _ in islice(g, 3)) for k, g in groupby(myList) if k]
[2, 1, 1]
>>> any(sum(1 for _ in islice(g, 3)) == 3 for k, g in groupby(myList) if k)
False
>>> myList = [True, True, False, False, True, True, True, True, False, True, False, False]
>>> [sum(1 for _ in islice(g, 3)) for k, g in groupby(myList) if k]
[2, 3, 1]
>>> any(sum(1 for _ in islice(g, 3)) == 3 for k, g in groupby(myList) if k)
True

我使用列表推导来显示组大小(仅计算True组),以显示any()调用首先返回False,然后True的原因;第二个示例包含一组4个连续的True值。

答案 1 :(得分:2)

我喜欢groupby的简洁,但我发现以下内容稍微有些可读性,所以我想我会添加一个替代方案;

needle = 3 * [True]
any(1 for i in range(len(myList)) if myList[i:i+len(needle)] == needle)

答案 2 :(得分:1)

这是我的解决方案

% cat hsol.py
import itertools

myList = [True, True, False, False, True, False, True, False, False]

def test_sequentiality(l, item, n):

    if n>len(l): return False
    s = 0
    for i in l:
        if i != item:
            s = 0
        else:
            s = s+1
            if s == n: return True

    return False

print test_sequentiality(myList, True, 3)
print test_sequentiality(myList, True, 2)
% python2 hsol.py
False
True
% 

答案 3 :(得分:0)

一种方法是减少问题中的if语句等,并直接打印布尔值。

for x0, x1, x2 in zip(myList, myList[1:], myList[2:]):
    print x0 == x1 == x2 == True

使用any语句,我们可以将相同的短路

any(x0 == x1 == x2 == True for (x0, x1, x2) in zip(myList, myList[1:], myList[2:]))

答案 4 :(得分:0)

print reduce(
             lambda acc, x: (acc[0]+1 if x else 0, max(acc[0], acc[1])),
             myList+[None],
             (0, 0)
             )[1]

如果最长的序列以最后一个元素结束,它将累积True的连续计数,并且需要最大数量的顺序True s +[None]

答案 5 :(得分:0)

直截了当(在我看来)非常容易理解的方式:

myList = [True, True, False, False, True, False, True, False, False]
v = True  # search for this value
n = 3  # number of consecutive appearances of v
vList = [v] * n

for i in range(len(myList) - n):
    if myList[i:i + n] == vList:
        print True
        break
else:
    print False

它是一种C风格(或Pascal或Fortran等),但很简单。上面的代码假设您最后只想要一个TrueFalse。如果要打印每个找到的事件的索引,可以轻松调整它。