Python 如何获取与列表中最大元素相邻的最大元素的索引

Python 如何获取与列表中最大元素相邻的最大元素的索引,python,list,Python,List,所以我有stock=[5,6,8,4,8,3,6,4]。我想得到最大元素的索引,与第一次出现的最大元素8相邻。所以我想要得到的是索引为1的6。我试过使用这个代码 closest=min(范围(长度(存量)),key=lambda i:abs(存量[i]-max(存量))) 但它只返回max元素。不是很漂亮,但它将满足所有可能的情况,即您的列表、max value a开始或结束、两个或一个值列表 代码是: def highest_neighbour(stock): if stock:

所以我有
stock=[5,6,8,4,8,3,6,4]
。我想得到最大元素的索引,与第一次出现的最大元素8相邻。所以我想要得到的是索引为1的6。我试过使用这个代码

closest=min(范围(长度(存量)),key=lambda i:abs(存量[i]-max(存量)))

但它只返回max元素。

不是很漂亮,但它将满足所有可能的情况,即您的列表、max value a开始或结束、两个或一个值列表

代码是:

def highest_neighbour(stock):
    if stock:
        x = stock.index(max(stock))
        if x - 1 >= 0:
            if x + 1 < len(stock):
                if stock[x + 1] > stock[x - 1]:
                    return x + 1
            return x - 1
        elif x + 1 < len(stock):
            return x + 1
        else:
            return -1
像这样:

stock = [5,6,8,7,8,3,6,4]

if stock.index(max(stock)) == len(stock)-1:
    print(len(stock)-2)
elif not stock.index(max(stock)):
    print(1)
elif stock[stock.index(max(stock))-1] > stock[stock.index(max(stock))+1]:
    print(stock.index(max(stock))-1)
else:
    print(stock.index(max(stock))+1)
输出:

1

虽然不是很优雅,但这应该是可行的:

stock.index(max(stock[stock.index(max(stock)) - 1], stock[(stock.index(max(stock)) + 1) % len(stock)]))
如果有可能看到值少于三个的列表,则必须添加处理

def max_neighbor_index(l: list):
    max_number = max(l)
    max_number_indexes = [x for x in range(0, len(l)) if l[x] == max_number]
    result = []
    for number_index in max_number_indexes:
        if number_index == 0:
            result.append(1)
        elif number_index == len(l) - 1:
            result.append(len(l) - 2)
        else:
            result.append(l.index(max([l[number_index - 1], l[number_index + 1]])))
    max_neighbor = max([l[x] for x in result])
    return [x for x in result if l[x] == max_neighbor][0]


stock = [5, 6, 8, 4, 8, 3, 6, 4]
print(max_neighbor_index(stock))

这将打印列表中第一次出现的最大值旁边的最高元素的索引
股票

stock = [1,5,8,4,8,7,6,4]

idx_max = stock.index(max(stock))
print(max([i for i in [idx_max-1, idx_max+1] if -1 < i < len(stock)], key=lambda k: stock[k]))

测试用例:

stock = [8,3,8,4,8,3,6,4]   # 1
stock = [1,3,1,3,8,5,6,4]   # 5
stock = [1,3,1,4,1,3,6,8]   # 6
stock = [1,5,8,4,8,7,6,4]   # 1

如果我正确理解了您的问题,最有趣的输入应该是
[1,5,8,4,8,7,6,4]
。也就是说,我们需要返回
5
的索引,因为它是最接近最大值第一次出现的第二个最大值。如果是,那么算法将如下所示:

find two leftmost and absolute maximums m1 and m2
if m1 == m2 then the target is in either of two subarrays:
    [0, pos(m1))
    [pos(m1) + 1, pos(m2))
otherwise, the target is in either of the following subarrays:
    [0, pos(m1))
    [pos(m1) + 1, len(arr))
我们可以在接近线性的时间内,使用。所以,我想我得到了一个线性的解决方案:

import heapq

def nlargest_with_pos(n, arr):
    assert len(arr) >= n
    largest = heapq.nlargest(n, ((it[1], -it[0]) for it in enumerate(arr)))
    return [(it[0], -it[1]) for it in largest]

def find_x(arr):
    assert len(arr) > 1

    first_max, second_max = nlargest_with_pos(2, arr)
    if len(arr) == 2:
        return second_max[1]

    left_range = (0, first_max[1])

    if second_max[0] == first_max[0]:
        right_range = (first_max[1] + 1, second_max[1])
    else:
        right_range = (first_max[1] + 1, len(arr))

    left_hand = arr[left_range[0]:left_range[1]]
    right_hand = arr[right_range[0]:right_range[1]]

    if not left_hand:
        return nlargest_with_pos(1, right_hand)[0][1]
    if not right_hand:
        return nlargest_with_pos(1, left_hand)[0][1]

    left_second_max = nlargest_with_pos(1, left_hand)[0]
    right_second_max = nlargest_with_pos(1, right_hand)[0]

    if left_second_max[0] >= right_second_max[0]:
        return left_second_max[1]
    else:
        return right_second_max[1]

print(find_x([1,5,8,4,8,7,6,4]))
这里有一个方法:

def get_max_neighbour(l):
    _max = max(l)
    excl = (-1, len(l))
    neighbour = max(
        (
            (l[j], j)
            for i in range(excl[-1])
            for j in (i-1, i+1)
            if l[i] == _max and j not in excl
        ),
        key=lambda x: x[0]
    )
    return neighbour[1]
结果:

1
这样做的好处是,如果需要,您可以同时返回值和索引。

stock=[5,6,8,4,8,3,6,4]
stock = [5,6,8,4,8,3,6,4]
idx = 1
tmp,nxt = stock[0:2]
for i in range(1, len(stock)):
    buf = stock[i-1] if i == len(stock)-1 else max(stock[i-1], stock[i+1])
    if tmp < stock[i] or (tmp == stock[i] and nxt < buf): 
        idx = stock.index(buf, i-1)
        nxt = stock[idx]
        tmp = stock[i]
print('greatest next to greatest', nxt, 'at', idx)
idx=1 tmp,nxt=库存[0:2] 对于范围(1,len(股票))内的i: buf=库存[i-1],如果i==len(库存)-1其他最大值(库存[i-1],库存[i+1]) 如果tmp
这是我解决这个难题的方法。我认为它与@DavidBuck的解决方案最为相似,因为
[8]
->
-1
[]
->
,但有四个较少的退出点:

from math import inf

def index_of_max_neighbor_of_max(array):
    if not array:
        return None

    index = array.index(max(array))
    a = array[index - 1] if index - 1 >= 0 else -inf
    b = array[index + 1] if index + 1 < len(array) else -inf
    return index + (b > a) * 2 - 1

因此,您希望找到第一个出现的最高元素,然后返回其最高相邻元素的索引?是的,如果最大值位于
股票
的任意一端,该怎么办?或者如果“第二个最大值”出现在其他地方?编辑以处理列表末尾的最高值。它将列表中的第一个和最后一个元素视为邻居。如果不需要的话,这可以很容易地修复。对于像
[5,6,8,4,8,3,6,9]
这样的列表,它返回了错误的值,因为它返回了前6个的索引。我认为它在
[1,5,8,4,8,7,6,4]
@IvanVelichko Yep,OP想要索引时失败了。更正了。
1
stock = [5,6,8,4,8,3,6,4]
idx = 1
tmp,nxt = stock[0:2]
for i in range(1, len(stock)):
    buf = stock[i-1] if i == len(stock)-1 else max(stock[i-1], stock[i+1])
    if tmp < stock[i] or (tmp == stock[i] and nxt < buf): 
        idx = stock.index(buf, i-1)
        nxt = stock[idx]
        tmp = stock[i]
print('greatest next to greatest', nxt, 'at', idx)
from math import inf

def index_of_max_neighbor_of_max(array):
    if not array:
        return None

    index = array.index(max(array))
    a = array[index - 1] if index - 1 >= 0 else -inf
    b = array[index + 1] if index + 1 < len(array) else -inf
    return index + (b > a) * 2 - 1
if __name__ == "__main__":

    iomnom = index_of_max_neighbor_of_max

    print(iomnom([5, 6, 8, 4, 8, 3, 6, 4]))  # 1
    print(iomnom([5, 6, 8, 4, 8, 3, 6, 9]))  # 6
    print(iomnom([5, 3]))  # 1
    print(iomnom([3, 5]))  # 0
    print(iomnom([8]))  # -1
    print(iomnom([]))  # None
    print(iomnom([5, 6, 8, 7, 8, 3, 6, 4]))  # 3
    print(iomnom([5, 6, 8, 4, 8, 3, 6, 9]))  # 6
    print(iomnom([5, 4, 8, 6, 8, 3, 6, 4]))  # 3