ren*_*nat 5 python random list
跳到上次编辑
我有一个Person
对象列表,我需要随机配对一个randomize_pairs
函数,每个Person
对象都有一个target
与之配对的属性.
我的约束是没有人可以自己配对(duh),他们不应该与同一个人配对两次.
如果约束条件得到满足,我会通过制作一个临时列表和弹出人员来解决这个问题,但我确信有更清洁/更好/更多的pythonic方法.谁知道?
我在这个问题中经常使用"对"这个词,但那是错误的.这是为了一个游戏,每个人被指定为另一个人作为目标,所以这些是你的目标的目标不一定是你的单向关系.
目标只会在每轮开始时改变,所以它一下子全部改变.
这就是我现在已经解决的问题,虽然它可以改进,所以我将问题保持开放.
def randomize_targets(players):
# get player count
count = len(players)
# copy the list of players
available_targets = list(players)
# shuffle the player order so if the last one has to have the same
# target twice it's not always the same player
players = list(players)
random.shuffle(players)
# loop over each player
for player in players:
# get the list of possible targets
potential_targets = [target for target in available_targets \
if target != player \
and target != player.target]
# try to pick one at random
try:
target = random.choice(potential_targets)
# if we have to, use the same target as last time
except IndexError:
pass
# remove the target from the available targets list
available_targets.remove(target)
# assign target
player.target = target
Run Code Online (Sandbox Code Playgroud)
我决定使用这种方法,即使我不喜欢潜在的长时间循环,直到它找到一个至少起作用的组合,它总是产生有效的结果
def randomize_targets2 (players):
targets = list(players)
# run this until it generates a valid result
valid = False
while not valid:
# randomize the targets
random.shuffle(targets)
# validate them
round_valid = True
for player, target in zip(players, targets):
round_valid = round_valid and player != target and player.target != target
valid = round_valid
# apply the validated targets
for player, target in zip(players, targets):
player.target = target
Run Code Online (Sandbox Code Playgroud)
我假设因为你想随机选择人,你选择的列表提供快速随机访问.一个简单的解决方案就是对整个列表进行洗牌,然后从列表的前面成对配对.
在费雪耶茨洗牌是随机洗牌列表中的快捷,简便的方法.
然后你可以直接将它们配对:
for x from 0 to persons.size(), x += 2
pair(persons.get(i), persons.get(i + 1));
Run Code Online (Sandbox Code Playgroud)
由于元素是独一无二的,您不必担心人们会两次配对或与自己配对.
还要小心确保您的清单首先有偶数人!如果总数是奇数,你将不得不以某种方式处理列表末尾的额外人员.
归档时间: |
|
查看次数: |
3207 次 |
最近记录: |