简体   繁体   English

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

[英]find if element appears n times in a row in python list

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

I want to find if True appears 3 times in a row. 我想找到True是否连续出现3次。

I can find it by doing: 我可以通过这样做找到它:

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

Is there a better way? 有没有更好的办法?

Use itertools.groupby() to group elements, then count each group. 使用itertools.groupby()对元素进行分组,然后对每个组进行计数。 Using the any() function lets you exit the loop early if a match was found: 如果找到匹配项,使用any()函数可以提前退出循环:

from itertools import groupby, islice

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

The if k filters the groups to only count the groups of True values. if k过滤组仅计算True值组。

The itertools.islice() function ensures we only look at the first 3 elements of a group, and ignore the rest of that group. itertools.islice()函数确保我们只查看组的前3个元素,并忽略该组的其余部分。 This way you avoid having to count the next however many True values just to determine that you found at least 3. 这样你就可以避免计算下一个很多True值,只是为了确定你找到了至少3个。

Demo: 演示:

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

I used a list comprehension to show the group sizes (counting only True groups) to show why the any() call returns False first, then True ; 我使用列表推导来显示组大小(仅计算True组)以显示为什么any()调用首先返回False ,然后返回True ; the second example has a group of 4 consecutive True values. 第二个例子有一组4个连续的True值。

I like the brevity of the groupby , but I find the following slightly more readable so I thought I'd add an alternative; 我喜欢groupby的简洁,但我觉得下面的内容稍微有些可读性,所以我想我会添加一个替代方案;

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

Here it is my solution 这是我的解决方案

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

One way would be to reduce the if statements etc in your question, and directly print the boolean value. 一种方法是减少问题中的if语句等,并直接打印布尔值。

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

Using any statement, we can short circuit the same 使用any语句,我们都可以短路

any(x0 == x1 == x2 == True for (x0, x1, x2) in zip(myList, myList[1:], myList[2:]))
print reduce(
             lambda acc, x: (acc[0]+1 if x else 0, max(acc[0], acc[1])),
             myList+[None],
             (0, 0)
             )[1]

It will accumulate the sequential counts of True with maximal count of sequential True s +[None] is needed in case the longest sequence ends with last element. 如果最长序列以最后一个元素结束,它将累积顺序计数True ,最大计数顺序为True s +[None]

A straightforward and (in my opinion) very easy-to-understand way: 一个直截了当的(在我看来)非常容易理解的方式:

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

It's kind of C-style (or Pascal or Fortran, etc.), but simple. 它有点C风格(或Pascal或Fortran等),但很简单。 The above code assumes you just want a single True or False at the end. 上面的代码假设您最后只需要一个TrueFalse You can easily adapt it if you want to print the index of each found occurrence. 如果要打印每个找到的事件的索引,可以轻松调整它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM