我有一个True
和False
的列表,它被认为是循环的(第一个元素位于最后一个元素之后)。找到最接近True
元素的索引的更好方法是什么,在元素之前具有给定索引?
这是我的解决方案。我认为它非常简单,但不是非常pythonic:
def prev_element(a, i):
i -= 1
while not a[i]:
i -= 1
return i % len(a)
如果没有这样的元素,这将引发IndexError
,这对我来说没问题。我利用了一个事实,即列表可以用负索引编制索引,这使得列表循环。更好的解决方案?一些很酷的单行,也许?
答案 0 :(得分:3)
from itertools import count
def prev_element(a, i):
cyc = count(i - 1, -1)
res = next((next(cyc) + 1 for _ in range(len(a)) if a[next(cyc)]), None)
return res % len(a) if res else res
你可以使用max with try / except使用lambda获取max,在约束条件下它不能小于我们搜索的索引,如果我们没有下面的索引,它将获得上面的索引。< / p>
def prev_element(a, ind):
try:
return max((i for i, ele in enumerate(a) if ele and i != ind), key=lambda x: (x < ind, x))
except ValueError:
return None
没有尝试/除了使用列表:
def prev_element(a, ind):
inds = [i for i, ele in enumerate(a) if ele and i != ind]
return max(inds,key=lambda x: (x < ind, x)) if inds else None
答案 1 :(得分:1)
我会这样做
def prev_element(seq, idx):
for new_idx,el in enumerate(reversed(seq[:idx])):
if el == True:
return idx - new_idx
另一个选项是:
def prev_element(seq, idx):
max(i for i,el in enumerate(seq[:idx]) if el==True)
甚至:
def prev_element(seq, idx):
min([i for i,el in enumerate(seq) if el==True], key=lambda i: abs(idx-i))
答案 2 :(得分:1)
对JuniorCompressor's answer的改进,这是最简单和最愚蠢的方法:
next(i%len(a) for i in range(n-1,n-len(a)-1,-1) if a[i])
其中n
是初始值的索引。