Python 生成所有置换的随机子集
我正在寻找一种方法来随机抽样所有排列的固定长度子集Python 生成所有置换的随机子集,python,permutation,itertools,Python,Permutation,Itertools,我正在寻找一种方法来随机抽样所有排列的固定长度子集 import itertools from random import shuffle mylist = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T'] 接近A 下面的方法A存在排列太相似的问题 a_pre = itertools.permutations(mylist,20) a = itertools.islice(a_p
import itertools
from random import shuffle
mylist = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T']
接近A
下面的方法A存在排列太相似的问题
a_pre = itertools.permutations(mylist,20)
a = itertools.islice(a_pre,3)
list(a)
['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','p','Q','R','S','T']
['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','p','Q','R','T','S']
['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','p','Q','S','R','T']
方法B
方法B使我更接近我想要的结果,但这里总是存在在列表之间产生相同顺序的风险,所以这种方法是不可行的
#repeat n=3 times
shuffle(mylist)
print(mylist)
[J',B',M',A',O',C',K',S',H',Q',N',T',R',D',G',p',I',E',F',L']
[R',O',C',I',G',E',Q',L',p',J',F',N',A',B',H',T',D',K',M',S']
[L',O',I',G',B',E',R',A',D',N',J',S',H',F',K',M',Q',T',C',p']
但在这里,列表之间总是有产生相同顺序的风险,所以这种方法是不可行的
#repeat n=3 times
shuffle(mylist)
print(mylist)
您可以使用元组(因为列表是不可散列的)和集合(这样就没有重复/相同的列表)来解决这个问题:
from random import shuffle
mylist = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T']
myset = set()
while len(myset) < 5: #change 5 to however many you want
shuffle(mylist)
myset.add(tuple(mylist))
print([list(x) for x in myset])
来自随机导入洗牌
mylist=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T']
myset=set()
而len(myset)<5:#将5更改为您想要的数量
洗牌(mylist)
添加(元组(mylist))
打印([myset中x的列表(x)])
编辑:正如所指出的:
对于给定的列表,有20个!=2432902008176640000种不同的排列,所以碰撞的可能性非常小
我认为你的问题是,k=N的一个特例 在此基础上,应适用其中所述的两种解决方案。第一个有点慢:) 所以随机抽样(你也暗示了你的问题,只需丢弃重复项…)似乎是目前唯一的答案 这将是非常有趣的,看看是否有一个生成性的解决方案,无论是这个问题,或更普遍的一个。。。 以下是基于该答案的代码:
import itertools
from random import shuffle
mylist = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T']
n=len(mylist)
k = n
m = 5
samples = set()
tries = 0
while len(samples) < m:
samples.add(tuple(random.sample(mylist,k)))
print (len(samples))
print(samples)
print(tries)
导入itertools
从随机导入洗牌
mylist=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T']
n=len(mylist)
k=n
m=5
样本=集合()
尝试=0
而len(样品)
您可以使用它来生成编号
-th个N
元素的词典阅读:
def permutation_from_int(N, number):
'''
get the number-th lexicographic permutation of length N.
N: the length of the permutation
0 <= number <= factorial(N) -1: the number of the desired
permutation
'''
# assert 0 <= number < factorial(N)
ret = [None] * N
select = list(range(N))
for i in range(N - 1, -1, -1):
index, number = divmod(number, factorial(i))
element = select[index]
ret[N - 1 - i] = element
select.remove(element)
return ret
请注意,如果测试的数量大于所有排列的空间,则这可能会永远循环
哪些打印(例如):
但正如其他答案中所提到的:如果你有一个20个元素的排列,那么重复排列的机会非常小 考虑一下itertools:
从文档中:
def random_permutation(iterable, r=None):
"Random selection from itertools.permutations(iterable, r)"
pool = tuple(iterable)
r = len(pool) if r is None else r
return tuple(random.sample(pool, r))
代码
import string
import more_itertools as mit
iterable = string.ascii_uppercase[:-6]
[random_permutation(iterable) for _ in range(3)]
输出
[('M', 'K', 'Q', 'A', 'I', 'J', 'H', 'T', 'C', 'E', 'P', 'L', 'B', 'N', 'G', 'F', 'S', 'D', 'O', 'R'),
('A', 'G', 'I', 'S', 'E', 'T', 'B', 'Q', 'D', 'M', 'C', 'O', 'J', 'H', 'N', 'F', 'K', 'P', 'R', 'L'),
('C', 'S', 'O', 'H', 'I', 'K', 'A', 'G', 'D', 'B', 'R', 'E', 'L', 'T', 'M', 'N', 'F', 'P', 'Q', 'J')]
是为您提供的第三方库。您希望生成多少排列?您可以将已使用的列表存储在一个集合中(例如,将列表连接到字符串后,或将其转换为元组后),并避免使用已使用的列表。对于给定列表,有20个!=2432902008176640000个不同的排列,因此碰撞的可能性非常小。可能的重复可能会增加遇到重复的可能性(对于给定列表来说非常非常低)。
[('M', 'K', 'Q', 'A', 'I', 'J', 'H', 'T', 'C', 'E', 'P', 'L', 'B', 'N', 'G', 'F', 'S', 'D', 'O', 'R'),
('A', 'G', 'I', 'S', 'E', 'T', 'B', 'Q', 'D', 'M', 'C', 'O', 'J', 'H', 'N', 'F', 'K', 'P', 'R', 'L'),
('C', 'S', 'O', 'H', 'I', 'K', 'A', 'G', 'D', 'B', 'R', 'E', 'L', 'T', 'M', 'N', 'F', 'P', 'Q', 'J')]