简体   繁体   中英

How to "filter" out a list in Python , without losing the index

We have a group of people. They are randomly assigned a number each week from 0 to 10 and if the number is greater than 9 so they become leaders .If they are more than 1 people, they all become leaders, if they don't , they vote themselves for the leader. A person can't be a leader for more than 2 times in a row.

Anyway, let's only have 10 people and give some random numbers , for this question :

import random

people=[]
for i in range(10):
    inputval = random.randint(0,10)
    people.append(inputval)

print(people)

So we get :

[5, 6 ,7, 4, 8, 3, 6, 7, 8, 9 ]

So , these are the values that correspond to the people.

people[0] = 5, people[1] = 6 and so on...

Leader is people[9]

The next week , we have

people = [8, 4 ,3, 2, 6, 10, 7, 6, 1, 9 ]

So the leaders are people[5] and people[9]

Next week we have:

people = [9, 0 ,4 , 8, 7, 6, 2, 3 , 1, 9 ]

So the leaders should be people[0] and people[9] but people[9] is already a leader 2 times in a row, so only people[0] should be leader. You get my drift. The problem is how to implement it.

  1. I can name which ones are leaders by enumerating the indices a but that's very "amateurish" way to only print the leaders of each week. I can't keep score of which actually are the leaders each time, with their corresponding indexes.

  2. I can also create a new list named leaders. I will run through the people list, if the value the element is 9 and over , it will append the new list with 1 (leader) or 0 (for non-leader), and have something like
    leaders1 = [0,0,0,0,0,0,0,0,0,1] , leaders2=[0,0,0,0,0,1,0,0,0,1] , printout each time only those with value 1, and compare with the previous leaders list, and probably implement a counter (?).

I find it more complicated in the long run, especially if I want to run this method for many weeks, thus creating more and more lists to compare.

What would be the best solution to that ? Any way to filter out the leaders, without losing the index of people, like [5], [9], etc? Maybe the solution shouldn't be with lists at all?

Thank you.

The problem you are facing is one of representation .
You are presenting it as "how to filter a list", but in fact, the problem is how to determine the successive leaders that are assigned following a strict set of rules.

There may be very clever ways to represent this with lists, or binary numbers, with bit shifting operations... this is the legacy of the pioneers of computer science that had to do things with very limited memory and very limited computer power...

You most likely do not have this problem, therefore you can represent your problem in an intelligible way, and leave code minimalistic antics to nostalgia and code golf.

Maybe modeling the problem with a class Person that keeps a historical record of successive scores and appointments as a leader, and is able to self determine if it currently qualifies as a leader?

import random


class Person:
    """stores a score, and a history of leadership, that allows it
    to decide if it qualifies a the current leader.
    """
    def __init__(self, ndx):
        self.ndx = ndx
        self.score_history = []
        self.leadership_history = []
    def add_new_score(self, score):
        self.score_history.append(score)
        self.current_leader()
    def current_leader(self):
        if self.score_history[-1] >= 9:
            current_leader = True
        else:
            current_leader = False
        if current_leader and len(self.score_history) >= 3:
            if self.leadership_history[-2] and self.leadership_history[-1]:
                current_leader = False
        self.leadership_history.append(current_leader)
    def is_current_leader(self):
        return self.leadership_history[-1]
    
def assign_score(people):
    for p in people:
        p.add_new_score(random.randint(0, 10))
        print(p.score_history[-1], end=' ')
    print()
        
def get_leaders(people):
    for p in people:
        if p.is_current_leader():
            print(p.ndx, end=' ')
    print()
    
people = [Person(idx) for idx in range(10)]
print()
for _ in range(20):
    print(_, end='\n')
    assign_score(people)
    get_leaders(people)
#     input()
    print()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM