Python:在循环列表中查找上一个和下一个“True”元素



循环列表中找到给定当前索引的前一个True元素的最佳方法是什么?

例如,给定这样的数据

my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
my_list_condition = [0, 0, 1, 1, 0, 1, 1]
  1. 查找上一个元素
before_e = find_prev('e', my_list, my_list_condition)
# before_e should be 'd'
before_c = find_prev('c', my_list, my_list_condition)
# before_c should be 'g' because it's circular list and the first True element before c is g
  1. 查找下一个元素
after_e = find_next('e', my_list, my_list_condition)
# after_e should output 'f'
after_g = find_next('g', my_list, my_list_condition)
# after_g should output 'c' because it's circular list and the first True element after c is g
您可以使用

itertools.cycle And itertools.compress来查找下一个元素,确保循环循环并仅循环所需的项目,但确保保留条件中的元素,一旦完成,那么找到前一个只是反向找到下一个:

from itertools import cycle, compress
def find_next(c, lst, lst_condition):
    condition = lst_condition[:]
    condition[lst.index(c)] = 1
    elems = cycle(compress(lst, condition))
    for elem in elems:
        if elem == c:
            return next(elems)
def find_prev(c, lst, lst_condition):
    return find_next(c, list(reversed(lst)), list(reversed(lst_condition)))

测试:

my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
my_list_condition = [0, 0, 1, 1, 0, 1, 1]
find_prev('e', my_list, my_list_condition) #d
find_prev('c', my_list, my_list_condition) #g
find_next('e', my_list, my_list_condition) # f
find_next('g', my_list, my_list_condition) #c

另一个例子:

from functools import partial
my_list = ["a", "b", "c", "d", "e", "f", "g"]
my_list_condition = [0, 0, 1, 1, 0, 1, 1]

def find_next(element, element_list, condition_list, backward=False):
    step = -1 if backward else 1
    next_index = element_list.index(element) + step
    length = len(element_list)
    while True:
        if next_index < 0 or next_index >= length:
            next_index = (next_index + length) % length
        if condition_list[next_index]:
            return element_list[next_index]
        next_index += step

find_prev = partial(find_next, backward=True)
print(find_prev("e", my_list, my_list_condition))
# d
print(find_prev("c", my_list, my_list_condition))
# g
print(find_next("e", my_list, my_list_condition))
# f
print(find_next("g", my_list, my_list_condition))
# c