在给出起始位置但后退的列表中找到第一个重合的索引

时间:2018-07-25 14:37:17

标签: python

在给定索引之前,是否有任何pythonic方法来找到第一个巧合?

例如,我想找到2之前的12之后的1

a = [0,2,0,0,1,0,0,2,0]

对于1之后的2,我使用此a.index(2,4)

有什么简单或干净的方法吗?

4 个答案:

答案 0 :(得分:4)

您可以反转列表并计算反转列表中“枢轴”元素的索引,然后照常使用index

def find_before(lst, e, idx):
    new_idx = len(lst) - idx - 1
    return len(lst) - lst[::-1].index(e, new_idx) - 1

值得注意的是,这对于庞大的列表来说是个坏主意,因为它在反转它时会临时创建一个副本。对于这种情况,一个更好的主意是blhsing做了什么,只是在列表中向后退一步:

def find_before(lst, e, idx):
    i = idx
    while i > 0:
        i -= 1
        if lst[i] == e:
        return i
    else:
        raise ValueError(f"No element {e} found before index {idx}")

答案 1 :(得分:2)

由于列表没有str.rindex的内置函数,因此您只需要自己做:

def rindex(lst, x, start=-1, end=0):
    if start < 0:
        start += len(lst)
    i = start
    while i >= end and lst[i] != x:
        i -= 1
    if i < 0:
        raise ValueError()
    return i

a = [0,2,0,0,1,0,0,2,0]
print(rindex(a, 2, 4))

这将输出:

1

答案 2 :(得分:1)

在O(n)中,您可以构建一个location来保存列表中任何元素的所有位置:

dict

查找一个元素的位置仅需进行一次O(1)操作:

a = [0,2,0,0,1,0,0,2,0]

pos = {}

for idx, elem in  enumerate(a):
    pos.setdefault(elem,set())
    pos[elem].add(idx)    

print(pos) # {0: {0, 2, 3, 5, 6, 8}, 2: {1, 7}, 1: {4}}

如果您想要第一次和最后一次发生,可以执行以下操作:

print(pos[2])  # {1,7}

您还可以查询其他内容:

print(min(pos[0]),max(pos[0])  #  0 8

关于1st 1之前和1st 1之后的2:

# get index of first 2 that is before the 1st 1
print( min(x for x in pos[2] if x < min(pos[1])))  # 1

# get index of all 0s that are after the 1st 1
print( list(x for x in pos[0] if x > min(pos[1])))  # [5, 6, 8]

输出:

firstOneIdx = min(pos[1]) # calc min index of 1 before, so it is not recalc'ed
print( "2 before 1st 1:" , list(x for x in pos[2] if x < firstOneIdx))
print( "2 after  1st 1:" , list(x for x in pos[2] if x > firstOneIdx))

您可以使用2 before 1st 1: [1] 2 after 1st 1: [7] 将列表减少到1个元素。

答案 3 :(得分:0)

答案可以分为三个子运算:将数组分成两个子数组,然后从末尾搜索第一个,然后从开头搜索第二个。

def index(array, value, pivot):

    def find(array):
        return array.index(value)

    first_half = arr[ (pivot - 1) : : -1 ]
    last_half = arr[ (pivot + 1) : ]
    return [ pivot - find(first_half) - 1, pivot + find(last_half) + 1 ]

从本质上讲,此方法将您的数组围绕pivot进行拆分,并向后重新排列第一个子数组。之后,您只需在两者中都找到value的第一个出现,它对应于数组中valuepivot的最近出现。它将像这样工作:

indexes = index(array, 2, 4)
# [1, 7]