循环赛的分组列表组合
Grouping list combinations for round-robin tournament
编辑:我的问题不是有人标记的重复问题。另一个问题不正确,甚至不起作用。
我尝试了几种方法来对 itertools.combinations 的结果进行分组,但无法得出正确的输出。需要在游戏中创建匹配项。每支球队每天都需要比赛,但只有一次。球队需要在接下来的几天打不同的球队,直到每个人都打完。
teams = [team 1, team 2, team 3, team 4]
print list(itertools.combinations(teams, 2))
结果:
[(team 1, team 2), (team 1, team 3), (team 1, team 4), (team 2, team 3), (team 2, team 4), (team 3, team 4)]
但我需要的是将它们分组,不要有任何重复的列表项。
示例:
[
[(team 1,team 2), (team 3,team 4)], #day 1
[(team 1,team 3), (team 2,team 4)], #day 2
[(team 1,team 4), (team 2,team 3)] #day 3
]
如有任何提示,我将不胜感激,我觉得可能有一个简单的单行代码就可以完成这项工作。
基于链接问题中的 Scheduling_algorithm 使用 collections.deque
的实现:
from collections import deque
from itertools import islice
def fixtures(teams):
if len(teams) % 2:
teams.append("Bye")
ln = len(teams) // 2
dq1, dq2 = deque(islice(teams, None, ln)), deque(islice(teams, ln, None))
for _ in range(len(teams)-1):
yield zip(dq1, dq2) # list(zip.. python3
# pop off first deque's left element to
# "fix one of the competitors in the first column"
start = dq1.popleft()
# rotate the others clockwise one position
# by swapping elements
dq1.appendleft(dq2.popleft())
dq2.append(dq1.pop())
# reattach first competitor
dq1.appendleft(start)
输出:
In [37]: teams = ["team1", "team2", "team3", "team4"]
In [38]: list(fixtures(teams))
Out[38]:
[[('team1', 'team3'), ('team2', 'team4')],
[('team1', 'team4'), ('team3', 'team2')],
[('team1', 'team2'), ('team4', 'team3')]]
In [39]: teams = ["team1", "team2", "team3", "team4","team5"]
In [40]: list(fixtures(teams))
Out[40]:
[[('team1', 'team4'), ('team2', 'team5'), ('team3', 'Bye')],
[('team1', 'team5'), ('team4', 'Bye'), ('team2', 'team3')],
[('team1', 'Bye'), ('team5', 'team3'), ('team4', 'team2')],
[('team1', 'team3'), ('Bye', 'team2'), ('team5', 'team4')],
[('team1', 'team2'), ('team3', 'team4'), ('Bye', 'team5')]]
编辑:我的问题不是有人标记的重复问题。另一个问题不正确,甚至不起作用。
我尝试了几种方法来对 itertools.combinations 的结果进行分组,但无法得出正确的输出。需要在游戏中创建匹配项。每支球队每天都需要比赛,但只有一次。球队需要在接下来的几天打不同的球队,直到每个人都打完。
teams = [team 1, team 2, team 3, team 4]
print list(itertools.combinations(teams, 2))
结果:
[(team 1, team 2), (team 1, team 3), (team 1, team 4), (team 2, team 3), (team 2, team 4), (team 3, team 4)]
但我需要的是将它们分组,不要有任何重复的列表项。 示例:
[
[(team 1,team 2), (team 3,team 4)], #day 1
[(team 1,team 3), (team 2,team 4)], #day 2
[(team 1,team 4), (team 2,team 3)] #day 3
]
如有任何提示,我将不胜感激,我觉得可能有一个简单的单行代码就可以完成这项工作。
基于链接问题中的 Scheduling_algorithm 使用 collections.deque
的实现:
from collections import deque
from itertools import islice
def fixtures(teams):
if len(teams) % 2:
teams.append("Bye")
ln = len(teams) // 2
dq1, dq2 = deque(islice(teams, None, ln)), deque(islice(teams, ln, None))
for _ in range(len(teams)-1):
yield zip(dq1, dq2) # list(zip.. python3
# pop off first deque's left element to
# "fix one of the competitors in the first column"
start = dq1.popleft()
# rotate the others clockwise one position
# by swapping elements
dq1.appendleft(dq2.popleft())
dq2.append(dq1.pop())
# reattach first competitor
dq1.appendleft(start)
输出:
In [37]: teams = ["team1", "team2", "team3", "team4"]
In [38]: list(fixtures(teams))
Out[38]:
[[('team1', 'team3'), ('team2', 'team4')],
[('team1', 'team4'), ('team3', 'team2')],
[('team1', 'team2'), ('team4', 'team3')]]
In [39]: teams = ["team1", "team2", "team3", "team4","team5"]
In [40]: list(fixtures(teams))
Out[40]:
[[('team1', 'team4'), ('team2', 'team5'), ('team3', 'Bye')],
[('team1', 'team5'), ('team4', 'Bye'), ('team2', 'team3')],
[('team1', 'Bye'), ('team5', 'team3'), ('team4', 'team2')],
[('team1', 'team3'), ('Bye', 'team2'), ('team5', 'team4')],
[('team1', 'team2'), ('team3', 'team4'), ('Bye', 'team5')]]