我是蟒蛇初学者,所以我想我可以在这里寻求帮助。
为简单起见,这里有两个输入列表,只有0和1:
x = [1, 1, 1, 0, 1]
y = [1, 1, 0, 1, 0]
我试图在python中定义一个逻辑,为x返回True 它有三个连续的元素,它们不等于零;索引0:2都不等于零。 相同的函数不会为y返回任何内容,因为y没有三个连续的元素不等于零。关于指数,我也意味着连续,而不是价值观!
除了解决这个逻辑之外,该函数还应该返回索引和3个非零元素的补丁的最后一个非零元素的值,以防原始条件为真。
所以,让我们说我有一个名为is_three_consecutive_non_zero的假设函数,这里是函数在两种情况下都会返回的函数:
is_three_consecutive_non_zero(x) # should evaluates to (True, 2, 1)
2是三个连续1的组中最后1个的索引,1是非零三个元素的补丁的最后一个非零元素的值!
如果第一个输出为false,则该函数不会返回任何其他内容。
这是一个烦人的三重嵌套for循环函数,有几个if条件可以作为一个很好的起点:
def is_three_consecutive_non_zero(list):
if 0 not in list:
return True, len(list)-1, list[len(list)-1]
for l in range(0, len(list)):
for m in range(1, len(list)):
for n in range(2, len(list)):
if (l != m) & (m != l) & (n == m + 1) & (m == l + 1):
if (list[l] != 0) & (list[m] != 0) & (list[n] != 0):
return True, n, list[n]
让我们试一试:
is_three_consecutive_non_zero(x)
is_three_consecutive_non_zero(y)
如果您可以分享任何更好的逻辑,或者可能是使用任何其他可用python模块的单个或两个班轮,那将是很棒的。 顺便说一句,这些列表非常小,所以,我不关心时间或空间问题。我也只关心三个非零元素的FIRST PATCH:
z = [0, 1, 1, 1, 1]
is_three_consecutive_non_zero(z) # evaluates to (True, 3, 1) which is consistent with what I want
非常感谢
答案 0 :(得分:2)
这是你要找的吗?
def f(l):
for i in range(len(l)-3):
if all(l[i:i+3]):
return True, i, l[i+2]
return False, None, None
如果你只是想回到列表中是否有三个这样的值,那么一个班轮就是any(all(l[i:i+3]) for i in range(len(l)-3))
答案 1 :(得分:2)
您可以使用itertools.groupby
对项目进行分组,然后检查非零组的长度。使用enumerate
:
from itertools import groupby
def is_three_consecutive_non_zero(lst):
for k, g in groupby(enumerate(lst), lambda p: p[1]):
g = list(g)
# check that key is not 0 and group length is more than 2
if k != 0 and len(g) > 2:
return True, g[-1][0], k
x = [1, 1, 1, 0, 1]
y = [1, 1, 0, 1, 0]
print is_three_consecutive_non_zero(x)
# (True, 2, 1)
print is_three_consecutive_non_zero(y) # should probably return a 3-item tuple
# None
答案 2 :(得分:1)
您可以使用此版本的功能。你可以避免大多数迭代。
def is_three_consecutive_non_zero(list):
if 0 not in list:
if len(list)>=3:
return True, len(list)-1, list[len(list)-1]
consecutiveNonZero=0
for index,num in enumerate(list):
if num is 0:
consecutiveNonZero = 0
else:
consecutiveNonZero = consecutiveNonZero+1
if consecutiveNonZero>=3:
return True, index,num
return False,-1,-1
答案 3 :(得分:0)
使用more_itertools
,我们找到所有索引并接受包含连续非零值的大小为n
的常规窗口。
import more_itertools as mit
def is_consecutive(seq):
"""Return True if a sequence is consecutively increasing."""
return tuple(seq) == tuple(range(seq[0], seq[-1]+1))
def consecutive_nonzero(lst, n=3):
"""Return True (bool, index, value) if windows are consecutively non-zero."""
grouped_idxs = [w for w in mit.windowed(mit.locate(lst), n) if is_consecutive(w)] # e.g. [(0, 1, 2)]
return [(True, grp[-1], lst[grp[-1]]) for grp in grouped_idxs]
consecutive_nonzero([1, 1, 1, 0, 1])[0]
# (True, 2, 1)
测试
import nose.tools as nt
def test_consecutive(f):
"""Verify results are consecutive and non-zero."""
nt.eq_(f([1, 1, 0, 1, 0]), [])
nt.eq_(f([1, 1, 1, 0, 1]), [(True, 2, 1)])
nt.eq_(f([1, 1, 1, 0, 1, 1, 1]), [(True, 2, 1), (True, 6, 1)])
nt.eq_(f([0, 1, 2, 3, 1]), [(True, 3, 3), (True, 4, 1)])
nt.eq_(f([0, 0, 1, 2, 3, 1, 1, 0], n=5), [(True, 6, 1)])
test_consecutive(f=consecutive_nonzero)