如何在不使用 numpy 的情况下将列表中的局部最小值和最大值切片到最后一项

How to slice local minima and maxima in a list till last item, without using numpy

提问人:codinguniverse 提问时间:10/25/2023 更新时间:10/27/2023 访问量:37

问:

我想通过一系列迭代来搜索局部最大值和最小值,直到列表只剩下一个元素。那么最后一个元素就是“赢家”。该列表包含玩家名称对,相应的整数用冒号分隔。
总之:

  1. 对于任何迭代,我都会从搜索最小值开始,然后仅当我当前的最小值列表还剩下一个元素时,我才继续检查最大值。
  2. 对于每次迭代,我只保留局部最小值和最小值的列表,因此显然列表会随着每次搜索/迭代而变小。
  3. 如果列表中还有多个元素,我会迭代,直到只有一个元素。
  4. 我希望能够看到完成了多少次迭代 - 使用变量“round”。
  5. 对于局部最小值搜索,仅当列表中的第一项小于下一项时,才会包含该项。此外,如果最后一个项目小于前一个项目,则包括该项目。反之亦然,用于局部极大值搜索。

问题是,在局部最小值搜索之后,当列表仍然有多个项目时,我似乎无法正确地进行局部最大值搜索和下一次迭代。所以结果似乎与我的预期不符。

这是我的代码。

def select_mid(players: str):

    player_list = players.split()  # Split the input string into individual name:identifier pairs
    ranks = [int(pair.split(":")[1]) for pair in player_list]  # Extract and convert the identifiers to integers

    minima_list = []
    maxima_list = []
    round = 0
    for i in range(1, len(ranks)):
        if len(player_list) > 1:
            # Here search is "current_rank < prev_rank and current_rank < next_rank"
            prev_rank, current_rank, next_rank = ranks[i-1], ranks[i], ranks[i] if i == len(ranks) - 1 else ranks[i+1]
            if current_rank < prev_rank and current_rank < next_rank:
                minima_list.append(player_list[i])
                player_list = minima_list 
            
            #Here search is "current_rank > prev_rank and current_rank > next_rank"
                if current_rank > prev_rank and current_rank > next_rank:
                    maxima_list.append(player_list[i])
                    player_list = maxima_list 
                round +=1 
                
        elif len(player_list) == 1:
            selection = player_list[0]
    
    return f"{selection} is selected in round: {round} "

# Example inputs:
    result = select_mid("Hulk:70 Kitana:83 Kunglao:20 goro:68 e:50 f:67 DE:40 Ef:177 Sindel:130 Konami:179 Fifa:95 ps:123 Fujin:101 name:134 Hola:89 Amari:205 Shakur:175 Rambo:303 Clay:33 Sheba:725 jaki:51")
    print(result)

我得到 Kunglao:20 作为第一轮的获胜者。所以很明显,我无法正确地进行最大值搜索并相应地迭代,直到最终列表有 1 个元素。

预期结果:

迭代1

minima1 绿巨人:70 昆劳:20 e:50 DE:40 辛德尔:130 国际足联:95 富晋:101 霍拉:89 沙库尔:175 粘土:33 贾基:51

最大值1 绿巨人:70 e:50 辛德尔:130 富晋:101 沙库尔:175 贾基:51

迭代2

minima2 e:50 富晋:101 jaki:51

最大值2 101

所以这里的获胜者是 101,在第 2 轮找到。

Python 列表 最大 最小值

评论


答:

0赞 Albert Lutakome 10/27/2023 #1

事实证明,我不得不重新考虑一切。发布答案,以防将来可能对某人有用。

def select_mid(all):
    rounds = 0  # Initialize the number of rounds to 0
    pairs_list = all.split()
    while len(pairs_list) > 1:
        rounds += 1  # Increment the round count at the start of each iteration
        local_minima = []  # List to store local minima
        local_maxima = []  # List to store local maxima

        # Search for local minima
        # Dealing with the first element in the list if its local less than next element
        if int(pairs_list[0].split(":")[1]) < int(pairs_list[1].split(":")[1]):
            local_minima.append(pairs_list[0])
            
        # Dealing with the elements within
        for i in range(1, len(pairs_list) - 1):
            name, rank = pairs_list[i].split(":")
            prev_rank = int(pairs_list[i - 1].split(":")[1])
            next_rank = int(pairs_list[i + 1].split(":")[1])

            if int(rank) < prev_rank and int(rank) < next_rank:
                local_minima.append(pairs_list[i])

        # Include the last item in local minima if it is a local minima
        if int(pairs_list[-1].split(":")[1]) < int(pairs_list[-2].split(":")[1]):
            local_minima.append(pairs_list[-1])

        # If there are local minima and more than one element, search for local maxima
        if local_minima and len(local_minima) > 1:
            if int(local_minima[0].split(":")[1]) > int(local_minima[1].split(":")[1]):
                local_maxima.append(local_minima[0])

            for i in range(1, len(local_minima) - 1):
                name, rank = local_minima[i].split(":")
                prev_rank = int(local_minima[i - 1].split(":")[1])
                next_rank = int(local_minima[i + 1].split(":")[1])

                if int(rank) > prev_rank and int(rank) > next_rank:
                    local_maxima.append(local_minima[i])

            # Include the last item in local maxima if it is a local maxima
            if int(local_minima[-1].split(":")[1]) > int(local_minima[-2].split(":")[1]):
                local_maxima.append(local_minima[-1])

            # Update the list with local maxima
            pairs_list = local_maxima
        else:
            # If there are no local maxima, update the list with local minima
            pairs_list = local_minima

    # Extract and print the name from the remaining pair
    if pairs_list:
        name, id = pairs_list[0].split(":")
        
    return f"The winner is {name} (id: {id}) selected in round {rounds}"

# Example list of pairs containing names and ranks
all = "Hulk:70 Kitana:83 Kunglao:20 goro:68 e:50 f:67 DE:40 Ef:177 Sindel:130 Konami:179 Fifa:95 ps:123 Fujin:101 name:134 Hola:89 Amari:205 Shakur:175 Rambo:303 Clay:33 Sheba:725 jaki:51"
result = select_mid(all)
print(result)

结果符合预期。