如何从单个列表中构建独特的随机对
How to build unique random couple from a single list
我想在一个列表中随机找到不同成员的情侣。
这是我的代码:
import random
def alea_couple(members):
couples = []
for p in members:
possibles = [r for r in members if r!=p and r not in [elem[1] for elem in couples]]
couples.append((p, random.choice(possibles)))
return couples
my_members = ["member1", "member2", "member3", "member4"]
random.shuffle(my_members)
alea_couple(my_members)
[('member2', 'member1'),
('member3', 'member4'),
('member1', 'member3'),
('member4', 'member2')]
我相信 itertools.combinations
有更好更优雅的方式来做到这一点
你有什么建议吗?
试试 itertools.permutations
:
import itertools
import random
def alea_couple(members):
perms = [p for p in itertools.permutations(members) if not any(x==y for x, y in zip(members, p))]
return list(zip(members, random.choice(perms)))
>>> alea_couple(["member1", "member2", "member3", "member4"])
[('member1', 'member4'),
('member2', 'member3'),
('member3', 'member1'),
('member4', 'member2')]
>>> alea_couple(["member1", "member2", "member3", "member4"])
[('member1', 'member4'),
('member2', 'member3'),
('member3', 'member2'),
('member4', 'member1')]
我认为这是一个实现 O(n),但性能可能无关紧要(请参阅下面的注释)。首先洗牌,然后按随机数量旋转。我已经 ,所以这里有类似的东西:
import random
import collections
def random_rotation(lst):
"""
Rotate a list by a random amount and return a deque.
Similar to "random.shuffle()", but ensures that all elements will move.
"""
n = random.randrange(1, len(lst))
d = collections.deque(lst)
d.rotate(n)
return d
def alea_couple(members):
members = random.sample(members, k=len(members)) # Copy and shuffle in one
pairs = random_rotation(members)
return list(zip(members, pairs))
示例输出:
>>> my_members = ["member1", "member2", "member3", "member4"]
>>> alea_couple(my_members)
[('member4', 'member3'),
('member1', 'member4'),
('member2', 'member1'),
('member3', 'member2')]
>>> alea_couple(my_members)
[('member3', 'member4'),
('member2', 'member1'),
('member4', 'member3'),
('member1', 'member2')]
来自the docs的注释:
even for small len(x)
, the total number of permutations of x
can quickly grow larger than the period of most random number generators. This implies that most permutations of a long sequence can never be generated. For example, a sequence of length 2080 is the largest that can fit within the period of the Mersenne Twister random number generator.
我想在一个列表中随机找到不同成员的情侣。
这是我的代码:
import random
def alea_couple(members):
couples = []
for p in members:
possibles = [r for r in members if r!=p and r not in [elem[1] for elem in couples]]
couples.append((p, random.choice(possibles)))
return couples
my_members = ["member1", "member2", "member3", "member4"]
random.shuffle(my_members)
alea_couple(my_members)
[('member2', 'member1'),
('member3', 'member4'),
('member1', 'member3'),
('member4', 'member2')]
我相信 itertools.combinations
你有什么建议吗?
试试 itertools.permutations
:
import itertools
import random
def alea_couple(members):
perms = [p for p in itertools.permutations(members) if not any(x==y for x, y in zip(members, p))]
return list(zip(members, random.choice(perms)))
>>> alea_couple(["member1", "member2", "member3", "member4"])
[('member1', 'member4'),
('member2', 'member3'),
('member3', 'member1'),
('member4', 'member2')]
>>> alea_couple(["member1", "member2", "member3", "member4"])
[('member1', 'member4'),
('member2', 'member3'),
('member3', 'member2'),
('member4', 'member1')]
我认为这是一个实现 O(n),但性能可能无关紧要(请参阅下面的注释)。首先洗牌,然后按随机数量旋转。我已经
import random
import collections
def random_rotation(lst):
"""
Rotate a list by a random amount and return a deque.
Similar to "random.shuffle()", but ensures that all elements will move.
"""
n = random.randrange(1, len(lst))
d = collections.deque(lst)
d.rotate(n)
return d
def alea_couple(members):
members = random.sample(members, k=len(members)) # Copy and shuffle in one
pairs = random_rotation(members)
return list(zip(members, pairs))
示例输出:
>>> my_members = ["member1", "member2", "member3", "member4"]
>>> alea_couple(my_members)
[('member4', 'member3'),
('member1', 'member4'),
('member2', 'member1'),
('member3', 'member2')]
>>> alea_couple(my_members)
[('member3', 'member4'),
('member2', 'member1'),
('member4', 'member3'),
('member1', 'member2')]
来自the docs的注释:
even for small
len(x)
, the total number of permutations ofx
can quickly grow larger than the period of most random number generators. This implies that most permutations of a long sequence can never be generated. For example, a sequence of length 2080 is the largest that can fit within the period of the Mersenne Twister random number generator.