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

4 投票
6 回答
3279 浏览
提问于 2025-04-27 23:23
myList = [True, True, False, False, True, False, True, False, False]

我想检查一下“True”这个词是不是连续出现了三次。

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

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

有没有更好的方法呢?

暂无标签

6 个回答

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 的结果。如果你想打印出每次找到的索引位置,也可以很容易地进行调整。

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

我喜欢groupby这个写法简洁明了,但我觉得下面这个写法稍微更容易理解,所以我想提供一个替代方案;

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

使用 itertools.groupby() 可以把元素分组,然后对每个组进行计数。通过使用 any() 函数,你可以在找到匹配项时提前退出循环:

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() 函数 确保我们只查看每个组的前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 值。

撰写回答