Есть ли способ найти лучшего человека из списка людей, а затем добавить его в список? - PullRequest
1 голос
/ 15 мая 2019

Я создаю список, в котором у меня есть несколько человек с навыками программирования и их курсами.Сейчас я в затруднении, потому что пытаюсь найти лучшего человека из этого списка приблизительно, основываясь на его навыках, покрываемых за доллар.какой алгоритм я должен использовать для оценки отдельных лиц?

Я продолжаю пытаться заставить цикл for повторяться, но он не перемещается позиционно.Он заканчивается после просмотра только первой ячейки.

jess = (["php", "java"], 200)

clark = (["php", "c++", "go"], 1000)

john = (["lua"], 500)

cindy = (["php", "go", "word"], 240)

candidates = [jess, clark, john, cindy]

project = ["php", "java", "c++", "lua", "go"]

def team_of_best_individuals(project, candidates):       

##note that in the list candidates, I tried to divide the number of items in the tuple by the cost, in order to find the skill per dollar

   def team_of_best_individuals(project, candidates):
   skillList = []
   for name in (candidates):
       len(name)
       for skill in name[0]:
            skillList.append(skill)

            if len(skillList) == len(name):
                num_of_skills=len(skillList)
                cost = name[1]
                num_skill_per_dollar = num_of_skills/cost
                return num_skill_per_dollar, candidates[0:4]
print("skill per dollar="+str(team_of_best_individuals(project, candidates)))

ожидаемый (выходной) должен быть человек, который покрывает наибольшее количество навыков на доллар.возвращаемое значение должно быть позиционным целым числом человека в списке.

например

0 - 4

Ответы [ 2 ]

2 голосов
/ 15 мая 2019

Хороший элегантный ответ @ Марк Мейер, я хотел бы добавить здесь один момент, который, как мне кажется, отсутствует в вашем вопросе.Нужно искать навыки, которые являются частью проекта.Если какой-либо навык, которым обладает кандидат, не является частью этого, его нужно сбрасывать со счетов.Я попытался написать что-то, что сделает это. Как он указал, может быть целесообразно иметь имена кандидатов отдельно вместо имени переменной.

jess = (["php", "java"], 200)

clark = (["php", "c++", "go"], 1000)

john = (["lua"], 500)

cindy = (["php", "go", "word"], 240)

candidates = [jess, clark, john, cindy]

project = ["php", "java", "c++", "lua", "go"]

def team_of_best_individuals(project, candidates):
    best = ('A', 0)
    for ind, candidate in enumerate(candidates):
        skills = candidate[0]
        skillperdollar = len([skill for skill in skills if skill in project])/candidate[1]
        if skillperdollar > best[1]:
            best = (ind, skillperdollar)
    return best
2 голосов
/ 15 мая 2019

Вы можете просто использовать max() и передать no_of_languages/cost в качестве ключа. Было бы проще, если бы имена были частью данных, а не именами переменных. Но если вам нужно работать с индексами, вы можете перечислить список и вернуть правильный индекс:

jess = (["php", "java"], 200)    
clark = (["php", "c++", "go"], 1000)
john = (["lua"], 500)
cindy = (["php", "go", "word"], 240)

candidates = [jess, clark, john, cindy]
m = max(enumerate(candidates), key=lambda cand: len(cand[1][0])/cand[1][1])
m[0] # 3 m[1] is the tuple

Включение имени в данные и использование чего-то вроде namedtuple значительно улучшает читабельность кода:

from collections import namedtuple
Candidate = namedtuple('Candidate', ('name', 'languages', 'cost'))

candidates = [
    Candidate('jess',["php", "java"], 200),
    Candidate('clark', ["php", "c++", "go"], 1000),
    Candidate('john',["lua"], 500),
    Candidate('cindy', ["php", "go", "word"], 240)
]

max(candidates, key=lambda cand: len(cand.languages)/cand.cost)
#Candidate(name='cindy', languages=['php', 'go', 'word'], cost=240)

Редактировать на основании упоминания @ Vasus-devon:

Вы можете найти пересечение проектов и навыка, используя наборы питона в операторе пересечения &. Чтобы найти лучшее совпадение, считая только навыки, которые пересекаются с проектом, вы можете рассчитать длину

set(project) & set(candidate.languages)

Вычисления, которые дают:

from collections import namedtuple
Candidate = namedtuple('Candidate', ('name', 'languages', 'cost'))
project = ["php", "java", "c++", "lua", "go"]

project_set = set(project) # make a set from projects

candidates = [Candidate('jess',["php", "java"], 200),
Candidate('clark', ["php", "c++", "go"], 1000),
Candidate('john',["lua"], 500),
Candidate('cindy', ["php", "go", "word"], 240)
]

# calculate project_set intersected with set(cand.languages)
max(candidates, key=lambda cand: len(project_set & set(cand.languages))/cand.cost)

результат:

Candidate(name='jess', languages=['php', 'java'], cost=200)
...