Home > front end >  How to get max() to return the first and second highest value in priority
How to get max() to return the first and second highest value in priority

Time:12-07

I'm working on a personality system for my game. Basically I'm trying to return the two highest values in a list without altering the list.

        social_sum = 0
        morals_sum = 0
        perception_sum = 0
        boldness_sum = 0
        for trait in self.traits:
            for personality in trait.personality:
                social_sum  = personality.social
                morals_sum  = personality.morals
                perception_sum  = personality.perception
                boldness_sum  = personality.boldness
                
        personality_list = [social_sum, morals_sum, perception_sum, boldness_sum]

There are 4 types of personalities (which may be positive or negative). The top two highest absolute values of those personalities will determine the persona of a character.

I've tried manually by using remove() and then doing the max() function again to return the second highest value. But that will alter personality_list and create other problems down the line. Here's my code, sorry if it looks really repetitive as I'm still learning the ropes.

        print(personality_list)
        personality_list = [abs(social_sum), abs(morals_sum), abs(perception_sum), abs(boldness_sum)]
        print(personality_list)
        first_personality = max(personality_list)

        for fp in personality_list:
            if first_personality == social_sum:
                fp = "Extrovert"
            elif -first_personality == social_sum:
                fp = "Introvert"
            elif first_personality == morals_sum:
                fp = "Idealist"
            elif -first_personality == morals_sum:
                fp = "Pragmatic"
            elif first_personality == perception_sum:
                fp = "Upright"
            elif -first_personality == perception_sum:
                fp = "Relaxed"
            elif first_personality == boldness_sum:
                fp = "Dominant"
            elif -first_personality == boldness_sum:
                fp = "Submissive"

        print(fp)
        personality_list.remove(first_personality)
        print(personality_list)

        second_personality = max(personality_list)

        for sp in personality_list:
            if second_personality == social_sum:
                sp = "Extrovert"
            elif -second_personality == social_sum:
                sp = "Introvert"
            elif second_personality == morals_sum:
                sp = "Idealist"
            elif -second_personality == morals_sum:
                sp = "Pragmatic"
            elif second_personality == perception_sum:
                sp = "Upright"
            elif -second_personality == perception_sum:
                sp = "Relaxed"
            elif second_personality == boldness_sum:
                sp = "Dominant"
            elif -second_personality == boldness_sum:
                sp = "Submissive"
        
        print(sp)

If the numbers align correctly the code works. Here is an example of the output:

[-35, -25, 10, 10]
[35, 25, 10, 10]
Introvert
[25, 10, 10]
Pragmatic

If there are two second highest numbers, the output still prioritize the list's index, which is what I want:

[5, 0, 35, -5]
[5, 0, 35, 5]
Upright
[5, 0, 5]
Extrovert

But if there are two equal absolute highest numbers, the output becomes like this:

[-5, -20, 20, 5]
[5, 20, 20, 5]
Upright
[5, 20, 5]
Upright

Any advice is appreciated. Thanks!

CodePudding user response:

My solution with sorting the list would be

from typing import List

personalities: List[List[str]] = [
    ["Extrovert", "Introvert"],
    ["Idealist", "Pragmatic"],
    ["Upright", "Relaxed"],
    ["Dominant", "Submissive"]
]

score: List[int] = [-5, -20, 20, 5]
sorted_indices: List[int] = [i[0] for i in sorted(enumerate(score), key=lambda k: abs(k[1]), reverse=True)]
for i in range(2): # Number of traits neeeded
    index: int = sorted_indices[i]
    secondary_index: int = 0
    if score[index] < 0:
        secondary_index = 1
    print(p[index][secondary_index])

Here, we get the indexes of the values in the order they would be in a sorted score list, without modifying the list itself, so it shouldn't impact the program down the line.
The sorting takes place at the declaration of sorted_indices and proceeds as follows: a list of pairs index, value is generated (enumerate(score)), then sorted in reverse according to the absolute value (sorted(enumerate(score), key=lambda k: abs(k[1]), reverse=True)), and finally we get rid of the value part, for we only need the indices (i[0] for i in ...).


Edit: to make a list out of the selected personnalities

from typing import List

personalities: List[List[str]] = [
    ["Extrovert", "Introvert"],
    ["Idealist", "Pragmatic"],
    ["Upright", "Relaxed"],
    ["Dominant", "Submissive"]
]
selected_personalities: List[str] = []

score: List[int] = [-5, -20, 20, 5]
sorted_indices: List[int] = [i[0] for i in sorted(enumerate(score), key=lambda k: abs(k[1]), reverse=True)]
for i in range(2): # Number of traits neeeded
    index: int = sorted_indices[i]
    secondary_index: int = 0
    if score[index] < 0:
        secondary_index = 1
    selected_personalities.append(personalities[index][secondary_index])

print(selected_personalities)
  • Related