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

时间:2019-05-27 05:52:58

标签: python

在循环列表中给定当前索引的情况下,找到上一个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

2 个答案:

答案 0 :(得分:2)

您可以使用itertools.cycleitertools.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

答案 1 :(得分:0)

另一个例子:

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