在Python列表中查找元素是否连续出现n次
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等),但很简单。上面的代码假设你只想在最后得到一个 True
或 False
的结果。如果你想打印出每次找到的索引位置,也可以很容易地进行调整。
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
值。