繁体   English   中英

在python中随机选择具有特定条件的列表中的项目

[英]Randomly selecting items from list with certain condition in python

我需要这些功能的一些帮助。 功能是我有一个员工列表,他们分为 3 个部分:manager、assist 和 emp。

以下是我创建的随机选择列表中 n 名员工的方法

list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
random.shuffle(list_sample)
total_num=4
temp_re_list=list_sample[:total_num]

我想要的功能是从列表中随机选择员工,但如果列表允许,可以根据特定条件进行选择。 例如,如果我需要 6 名员工,而从这 6 名员工中,我至少需要 2 名经理和 1 名助理。 如果该列表不包含经理或助理,那么它将尝试提供任何 emp,只要它给我相同的总 emp。 需要明确的是,list_sample 将允许大于或等于 total_num

list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]

total_num=6
manager_num=1
assist_num=2
emp_num=3

# another example of the list
list_sample=["Assist 1","Assist 2","Assist 4","Emp 2","Emp 3","Emp 5","Emp 6"]
manager_num=1
assist_num=2

目前,我正在考虑将 list_sample 分成多个列表,但我认为这不是一种有效的方法

import random
list_sample=["Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]

total_num=6
manager_num=1
assist_num=2
emp_num=3
res = []
manager_list=[]
assist_list=[]
emp_lists=[]
random.shuffle(list_sample)
for x in list_sample:
    if "Manager" in  x:
        manager_list.append(x)
    elif "Assist" in x:
        assist_list.append(x)
    elif "Emp" in x:
        emp_lists.append(x)


如果有人可以指导我如何开发此功能,那就太好了

谢谢

只需使用简单的随机和 if 条件,如下所示:

import random
list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]

total_num=6
manager_num=1
assist_num=2
emp_num=3
res = []
while total_num > 0:
    choice = random.choice(list_sample)
    if "Manager" in choice and manager_num > 0:
        res.append(choice)
        manager_num -= 1
        total_num -= 1
    elif "Assist" in choice and assist_num > 0:
        res.append(choice)
        assist_num -= 1
        total_num -= 1
    elif "Emp" in choice and emp_num > 0:
        res.append(choice)
        emp_num -= 1
        total_num -= 1
print(res)

注意:这是一种直接的方法,可以使用eval()等 Pythonic 技术进一步简化

我认为拆分成单独的列表不一定是个坏主意。 它将为您提供灵活性。

例如你可以做这样的事情


list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
random.shuffle(list_sample)

managers = [li for li in list_sample if li.startswith("Manager")]
assists = [li for li in list_sample if li.startswith("Assist")]
emps = [li for li in list_sample if li.startswith("Emp")]

managers_num = 4
assists_num = 1
emps_num = 3
total = managers_num + assists_num + emps_num
result = []
# Choose Managers
result.append(managers[:managers_num])
result.append(assists[:assists_num])
left = managers_num + assists_num - len(result)
result.append(emps[:emps_num+left])

无论如何,我认为不分组或排序数组将需要在整个列表上进行更多的循环迭代,这是低效的。

此解决方案允许您为角色选择员工类型。

例如,先按经理选经理,然后选助理,再选员工:

  • 指定 manager_categories = ["Man", "Ass", "Emp"](按员工的前 3 个字母分类)

代码

from random import shuffle

def select_emp(lst, 
               managers = 0,
               manager_categories = ['Man', 'Ass', 'Emp'],
               assistants = 0,
               assistants_categories = ['Ass', 'Emp'],
               employees = 0,
               employee_categories = ['Emp']):
    def selection(category, cnt, seen):
        ' Choose employees at random of a particular type (i.e. prefix) '
        options = [emp for emp in lst if emp.startswith(category) and emp not in seen] # possible employees
        shuffle(options)                                                               # random order
        return sorted(options[:cnt], key = lambda x: int(x.split()[1]))                # up to cnt of employees                                               # select up to cnt
                                                                                       # sorted by index
    
    def draw(categories, needed, seen):
        ''' Selects employees based on preferred order of categories
            For instance, if we need a certain number of managers we loop over the employee
            categories we allow until we satisfy the requriement
        '''
        allocated = []
        if needed > 0:
            for category in categories:
                allocated += selection(category, needed - len(allocated), seen)
                seen.update(allocated)
                if len(allocated) == needed:
                    break
            else:
                raise Exception('Not enought employees to satisfy constraint')
                
        return allocated
        
    seen = set()
    # Allocate managers, assistants, & employees
    managers = draw(manager_categories, managers, seen)
    assistants = draw(assistants_categories, assistants, seen)
    employees = draw(employee_categories, employees, seen)
        
    return managers, assistants, employees

用法

from pprint import pprint as pp   # pretty print

list_sample=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]

示例 1

使用默认经理、助理和员工类别

pp(select_emp(list_sample, 
          managers = 5, 
          assistants = 2, 
          employees = 3))
>>> (['Manager 1', 'Manager 2', 'Manager 3', 'Manager 4', 'Assist 2'],
     ['Assist 1', 'Assist 3'],
     ['Emp 2', 'Emp 3', 'Emp 6'])

示例 2

允许通过更改默认 manager_categories 从经理或员工中选择经理

pp(select_emp(list_sample, 
          managers = 5, 
          manager_categories = ['Man', 'Emp'], # changed default
          assistants = 2, 
          employees = 3))
>>> (['Manager 1', 'Manager 2', 'Manager 3', 'Manager 4', 'Emp 1'],
     ['Assist 2', 'Assist 3'],
     ['Emp 2', 'Emp 4', 'Emp 5'])
    

你的代码是高效的。 这是另一种做同样事情的方法。

import random
list_sample=["Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]

total_num=6
manager_num=1
assist_num=2
emp_num=3
res = []
manager_list=[]
assist_list=[]
emp_lists=[]

# Getting all the managers, assistants and employees
for x in list_sample:
    if x.startswith("Assist"):
        assist_list.append(x)
    elif x.startswith("Emp"):
        emp_lists.append(x)
    else:
        manager_list.append(x)

# Check if the number of managers, assistants and employees are correct
while len(manager_list) < manager_num:
    # Get random emp from emp_lists
    manager_list.append(emp_lists.pop(random.randint(0, len(emp_lists)-1)))

while len(assist_list) < assist_num:
    # Get random emp from emp_lists
    assist_list.append(emp_lists.pop(random.randint(0, len(emp_lists)-1)))

print("manager_list: ", manager_list)
print("assist_list: ", assist_list)
print("emp_lists: ", emp_lists)

输出:

manager_list:  ['Emp 4']
assist_list:  ['Assist 1', 'Assist 2', 'Assist 3', 'Assist 4']
emp_lists:  ['Emp 1', 'Emp 2', 'Emp 3', 'Emp 5', 'Emp 6']
peaple=["Manager 1","Manager 2","Manager 3","Manager 4","Assist 1","Assist 2","Assist 3","Assist 4","Emp 1","Emp 2","Emp 3","Emp 4","Emp 5","Emp 6"]
random.shuffle(peaple)
managers = [person for person in peaple if 'Manager' in person]
asistants = [person for person in peaple if 'Assist' in person]
employees = [person for person in peaple if 'Emp' in person]

selected = managers[:2] + asistants[:1]
remained = managers[2:] + asistants[1:] + employees

random.shuffle(remained)
selected = selected + remained[:3]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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