[英]Python--Combinations of three items from each of two lists for iteration
另一個編輯:我想我可能還沒有把問題弄清楚。 每個Person
都有各自可以執行的任務的列表,並且不能保證Person1
將始終具有列表中三個任務中的第一個。 我已經嘗試了答案中建議的一些方法,但是都沒有得到我想要的結果。 使用zip
和dict
只檢查使用Person
對象的組合,它們的使用順序與出現在列表中的順序相同,這給了我很多錯誤答案。 使用itertools.combinations
解決了這個問題,但是測試了itertools.combinations
可能的人員任務組合,這再次給了我很多我不想要的組合。
我要最終完成的工作是擁有一個bad_options
列表,其中包含三個tasks
所有集合,而這不能通過為每個person
分配一個task
來覆蓋。 我不需要每個排列(例如,如果三個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
東西嗎? 我想要的結果是字典列表,如:
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
將是未正確涵蓋的任務組合的列表,如果有的話,對嗎?
底線問題:如何獲取該字典列表,我的代碼對其進行迭代是否正確? 另外,我很樂意被告知有更好的方法可以實現目標。 為了獲得額外的榮譽,將來我將受益於確定一種方法來培訓每個人以使他們能夠涵蓋所有可能性(如果不清楚,或者可以回答第一個問題,但不能回答第一個問題),則可以從中受益。
不確定,但是也許這就是您所需要的(如果問題是如何獲取字典列表)
>>> 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}]
您可以使用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
您可以使用以下方法:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.