另一个编辑:
我想我可能没有说清楚这个问题。每个Person
都有一个单独的列表,列出了他们可以执行的任务,并且无法保证Person1
始终拥有列表中三个任务中的第一个。我已经尝试了一些在答案中提出的事情,但都没有得到我想要的结果。使用zip
和dict
只检查使用Person
个对象的组合,它们与列表中显示的顺序相同,这给了我一堆不正确的答案。使用itertools.combinations
解决了这个问题但测试了每一组可能的人 - 任务组合,这再次给了我一些我不想要的组合。
我想要最终实现的是列表bad_options
,其中包含通过为每个tasks
分配一个task
无法涵盖的所有三个person
的集合。我不需要每一个排列(例如,如果三个tasks
[Task1, Task3, Task6]
和Person1, Person3, Person2
按顺序排列,我不希望[Task1, Task3, Task6]
被添加到bad_options
。如果这还不够清楚,我会提前道歉;如果此时我应该提出一个新问题,请随意发表评论并说出来并且我会接受路由。
根据以下答案,我尝试过:
for setup in setups:
combo = dict(zip(setup, people))
possibilities.append(combo)
for setup in possibilities:
for task, person in setup.items():
if not task in person.tasks:
if not setup in bad_options:
bad_options.append(setup)
break
else:
pass
这将返回所有可能的任务组合,就好像它们都没有被覆盖一样,即使我直接设置每个person.tasks
以确保它们都应该有效且函数不返回任何内容。我现在做错了什么?
我需要结合以下内容:
tasks = ['Task1', 'Task2', 'Task3', 'Task4', 'Task5', ...]
people = [Person1, Person2, Person3]
每个Person
是一个类的实例,其中一个属性是人员可以执行的任务列表。我将不得不分配三个总任务,每个人一个。我想确保可用人员可以涵盖三个任务的所有可能组合。
我已经构建了代码,该代码将为我提供三个任务的所有可能组合的列表:
setups = (('Task1', 'Task2', 'Task3'),
('Task1', 'Task2', 'Task4'),
('Task1', 'Task2', 'Task5'), ...)
(之所以我单独做这个部分,是因为对于哪些任务组合可以组合起来还有限制,我已经编写了一个单独的脚本来消除非法组合。我不希望有复制这种努力,但如果以这种方式这样做可以这样做是愚蠢的。)
我认为我需要在for
上使用setups
循环,可能使用类似itertools.combinations
的内容?我正在寻找结果作为一个dicts列表,如:
options = [['Task1' : Person1, 'Task2' : Person2, 'Task3' : Person3],
['Task1' : Person1, 'Task2' : Person2, 'Task4' : Person3], ...]
我迷失了如何获得这个词典列表。我假设列表上的迭代类似于:
for option in options:
for task, person in option.items():
if task[0] in person[0].tasks and task[1] in person[1].tasks and task[2] in person[2].tasks:
True
else:
bad_options.append(option)
然后 bad_options
会列出未正确涵盖的任务组合(如果有的话),对吗?
底线问题:我如何获得该词典列表,并且我的代码是否正确迭代?或者,我很高兴被告知有更好的方法来实现目标。为了获得额外的功劳,我将来会从确定培训每个人的任务中获益,以便他们能够涵盖所有可能性(但如果不清楚或者你可以回答第一个问题,请忽略它)但不是这个。)
答案 0 :(得分:1)
不确定,但也许这就是你需要的(如果问题是如何获得dicts列表)
>>> import itertools
>>> tasks = ['Task1', 'Task2', 'Task3', 'Task4', 'Task5']
>>> people = [1, 2, 3]
>>> setups = itertools.combinations(tasks, len(people))
>>> options = [{task: person for task, person in zip(tasks, people)} for tasks in setups]
>>> options
[{'Task1': 1, 'Task2': 2, 'Task3': 3}, {'Task1': 1, 'Task2': 2, 'Task4': 3}, {'Task1': 1, 'Task2': 2, 'Task5': 3}, {'Task1': 1, 'Task3':
2, 'Task4': 3}, {'Task1': 1, 'Task3': 2, 'Task5': 3}, {'Task1': 1, 'Task4': 2, 'Task5': 3}, {'Task2': 1, 'Task3': 2, 'Task4': 3}, {'Tas
k2': 1, 'Task3': 2, 'Task5': 3}, {'Task2': 1, 'Task4': 2, 'Task5': 3}, {'Task3': 1, 'Task4': 2, 'Task5': 3}]
答案 1 :(得分:0)
您可以使用zip()
和dict()
options = []
for tasks in setup:
d = dict( zip(tasks, [Person1, Person2, Person3]) )
# {'Task1' : Person1, 'Task2' : Person2, 'Task3' : Person3}
options.append(d)
您的代码task
和person
是单个元素,而不是列表 - 您无法使用[0]
,[1]
等。
但你可以做(使用for/break/else
构建)
for option in options:
for task, person in option.items(): # single elements
if task not in person.tasks:
bad_options.append(option)
break
else: # for/break/else construction
print "OK:", option
答案 2 :(得分:0)
您可以使用以下方法:
class Person(object):
def __init__(self, id):
self.id = id # assign a simple ID to each Person
Person1 = Person(1)
Person2 = Person(2)
Person3 = Person(3)
people = [Person1, Person2, Person3]
setups = (
('Task1', 'Task2', 'Task3'),
('Task1', 'Task2', 'Task4'),
('Task1', 'Task2', 'Task5'))
# Create a list of dictionaries combining each setup with people
options = [dict(zip(setup, people)) for setup in setups]
# Display the list
for option in options:
for key, person in option.items():
print key, person.id
print
这会给你以下输出:
Task1 1
Task2 2
Task3 3
Task1 1
Task2 2
Task4 3
Task1 1
Task2 2
Task5 3