python 排列组合,在Python中对所有嵌套列表(列表列表)中的所有元素进行无序排列/排列组合?...

博客讨论了如何生成嵌套列表的随机无序排列,而不是按顺序排列。提供了一个使用`random_perm`生成器函数的例子,该函数在每次迭代时返回一个随机选择的子列表元素组合,从而实现无序的全排列。然而,由于没有缓存结果,无法确保不重复,并且可能无法在连续的迭代中获取所有独特排列。
摘要由CSDN通过智能技术生成

I have two-level nested list like following.

[[0, 1], [2], [3, 4], [5, 5], [6], [7], [8], [9], [10, 11], [12]]

I want to generate all 8 unique permutations of this nested list, but my application absolutely needs the output to be (pseudo-)randomized and unordered. Usually, permutation strategies produce the permutations in order, but I want to be able to produce all permutations out of order.

Moreover, this MUST be done through some generator, as the nested list can be very long, and number of unique permutations can explode combinatorially.

Case in point, the following output is desired for the above list.

(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)

...as opposed to the following, which is generated by 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)

Even some solution that does exactly what itertools.product does, but generates permutations out of order will help me a lot. Any help is appreciated.

The following code illustrates my existing approach.

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

解决方案

You can try iterating over the following generator:

def random_perm(l):

while True:

yield [random.choice(sublist) for sublist in l]

Sample usage:

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))

Output:

[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]

However, as others have pointed out in the comments, unless you cache the yield results in memory somehow, you can't really guarantee you won't get duplicates. You are also not guaranteed to get all 8 unique iterations in any 8 consecutive iterations.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值