我有两级嵌套列表,如下所示。
[[0, 1], [2], [3, 4], [5, 5], [6], [7], [8], [9], [10, 11], [12]]
我希望生成此嵌套列表的所有8个唯一排列,但我的应用程序绝对需要输出(伪)随机和无序。通常,排列策略按顺序产生排列,但我希望能够不按顺序产生所有排列。
此外,这个MUST
可以通过某个生成器完成,因为嵌套列表可能非常长,并且唯一排列的数量可以组合爆炸。
例如,以上列表需要以下输出。
(0, 2, 3, 5, 6, 7, 8, 9, 10, 12)
(1, 2, 3, 5, 6, 7, 8, 9, 10, 12)
(0, 2, 3, 5, 6, 7, 8, 9, 11, 12)
(1, 2, 4, 5, 6, 7, 8, 9, 10, 12)
(0, 2, 4, 5, 6, 7, 8, 9, 10, 12)
(1, 2, 3, 5, 6, 7, 8, 9, 11, 12)
(1, 2, 4, 5, 6, 7, 8, 9, 11, 12)
(0, 2, 4, 5, 6, 7, 8, 9, 11, 12)
...而不是由itertools.product(* some_list)生成的以下内容:
(0, 2, 3, 5, 6, 7, 8, 9, 11, 12)
(0, 2, 3, 5, 6, 7, 8, 9, 10, 12)
(0, 2, 3, 5, 6, 7, 8, 9, 11, 12)
(0, 2, 3, 5, 6, 7, 8, 9, 10, 12)
(0, 2, 4, 5, 6, 7, 8, 9, 11, 12)
(0, 2, 4, 5, 6, 7, 8, 9, 10, 12)
(0, 2, 4, 5, 6, 7, 8, 9, 11, 12)
(0, 2, 4, 5, 6, 7, 8, 9, 10, 12)
(1, 2, 3, 5, 6, 7, 8, 9, 11, 12)
(1, 2, 3, 5, 6, 7, 8, 9, 10, 12)
(1, 2, 3, 5, 6, 7, 8, 9, 11, 12)
(1, 2, 3, 5, 6, 7, 8, 9, 10, 12)
(1, 2, 4, 5, 6, 7, 8, 9, 11, 12)
(1, 2, 4, 5, 6, 7, 8, 9, 10, 12)
(1, 2, 4, 5, 6, 7, 8, 9, 11, 12)
(1, 2, 4, 5, 6, 7, 8, 9, 10, 12)
即使是一些与itertools.product完全相同的解决方案,但是无序生成排列也会对我有所帮助。任何帮助表示赞赏。
以下代码说明了我现有的方法。
def perm_attempt():
meta_seq = [[0, 1], [2], [3, 4], [5, 5], [6], [7], [8], [9], [10, 11], [12]]
print meta_seq
iter_count = np.prod([len(set(x)) for x in meta_seq])
print iter_count
print
set_l = set()
for _ in xrange(iter_count*10):
l = [np.random.choice(x) for x in meta_seq]
# print l
set_l.add(tuple(l))
print
print len(set_l)
print
# for s in set_l:
# print s
答案 0 :(得分:1)
您可以尝试迭代以下生成器:
def random_perm(l):
while True:
yield [random.choice(sublist) for sublist in l]
样本用法:
l = [[0, 1], [2], [3, 4], [5, 5], [6], [7], [8], [9], [10, 11], [12]]
g = random_perm(l)
for _ in range(10):
print(next(g))
输出:
[0, 2, 4, 5, 6, 7, 8, 9, 10, 12]
[1, 2, 4, 5, 6, 7, 8, 9, 11, 12]
[0, 2, 3, 5, 6, 7, 8, 9, 10, 12]
[0, 2, 3, 5, 6, 7, 8, 9, 10, 12]
[0, 2, 3, 5, 6, 7, 8, 9, 11, 12]
[1, 2, 4, 5, 6, 7, 8, 9, 10, 12]
[0, 2, 3, 5, 6, 7, 8, 9, 11, 12]
[1, 2, 4, 5, 6, 7, 8, 9, 11, 12]
[1, 2, 4, 5, 6, 7, 8, 9, 10, 12]
[0, 2, 4, 5, 6, 7, 8, 9, 10, 12]
然而,正如其他人在评论中指出的那样,除非你以某种方式将收益结果缓存在内存中,否则你无法保证你不会获得重复。您也无法保证在任何8次连续迭代中获得所有8次独特迭代。
答案 1 :(得分:0)
如果内存不是问题,您可以尝试以下方法:
permList = itertools.product(*list_of_lists)
randomPermList = numpy.random.permutation(list(permList))
这是唯一且随机的,但不会是迭代。
答案 2 :(得分:0)
比你目前的解决方案更清洁一点:
meta_seq = [[0, 1], [2], [3, 4], [5, 5], [6], [7], [8], [9], [10, 11], [12]]
print meta_seq
iter_count = np.prod([len(set(x)) for x in meta_seq])
print iter_count
print
set_l = set()
for _ in xrange(iter_count*100):
choices = tuple([np.random.choice(sub_seq) for sub_seq in meta_seq])
if not choices in set_l:
set_l.add(choices)
print choices
print
print len(set_l)
print