在给定索引之前,是否有任何pythonic方法来找到第一个巧合?
例如,我想找到2
之前的1
和2
之后的1
。
a = [0,2,0,0,1,0,0,2,0]
对于1之后的2
,我使用此a.index(2,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
的第一个出现,它对应于数组中value
到pivot
的最近出现。它将像这样工作:
indexes = index(array, 2, 4)
# [1, 7]