繁体   English   中英

python中数组的所有排列

[英]All permutations of an array in python

我有一个数组。 我想从该数组生成所有排列,包括单个元素、重复元素、更改顺序等。例如,假设我有这个数组:

arr = ['A', 'B', 'C']

如果我通过这样做来使用itertools模块:

from itertools import permutations
perms = [''.join(p) for p in permutations(['A','B','C'])]
print(perms)

或者像这样使用循环:

def permutations(head, tail=''):
if len(head) == 0:
    print(tail)
else:
    for i in range(len(head)):
        permutations(head[:i] + head[i+1:], tail + head[i])
        
arr= ['A', 'B', 'C']
permutations(arr)

我只得到:

['ABC', 'ACB', 'BAC', 'BCA', 'CAB', 'CBA']

但我想要的是:

['A', 'B', 'C', 
 'AA', 'AB', 'AC', 'BB', 'BA', 'BC', 'CA', 'CB', 'CC', 
 'AAA', 'AAB', 'AAC', 'ABA', 'ABB', 'ACA', 'ACC', 'BBB', 'BAA', 'BAB', 'BAC', 'CCC', 'CAA', 'CCA'.]

结果是给定数组的所有排列。 由于数组是3个元素,所有元素都可以重复,所以它生成3^3(27)种方式。 我知道必须有一种方法可以做到这一点,但我不能完全理解正确的逻辑。

一个生成器,可以按照您的描述生成所有序列(如果您尝试耗尽它,它的长度是无限的):

from itertools import product


def sequence(xs):
    n = 1
    while True:
        yield from (product(xs, repeat=n))
        n += 1


# example use: print first 100 elements from the sequence
s = sequence('ABC')
for _ in range(100):
    print(next(s))

Output:

('A',)
('B',)
('C',)
('A', 'A')
('A', 'B')
('A', 'C')
('B', 'A')
('B', 'B')
('B', 'C')
('C', 'A')
('C', 'B')
('C', 'C')
('A', 'A', 'A')
('A', 'A', 'B')
('A', 'A', 'C')
('A', 'B', 'A')
...

当然,如果您不想要元组,而是字符串,只需将next(s)替换为''.join(next(s)) ,即:

    print(''.join(next(s)))

如果您不希望序列超过原始集合的长度:

from itertools import product


def sequence(xs):
    n = 1
    while n <= len(xs):
        yield from (product(xs, repeat=n))
        n += 1


for element in sequence('ABC'):
    print(''.join(element))

当然,在这种有限的情况下,这也可以:

from itertools import product

xs = 'ABC'
for s in (''.join(x) for n in range(len(xs)) for x in product(xs, repeat=n+1)):
    print(s)

编辑:在评论中,OP 要求解释yield from (product(xs, repeat=n))

product()itertools中的一个 function ,它生成可迭代对象的笛卡尔积,这是一种奇特的方式,可以说您从第一个可迭代对象中获得所有可能的元素组合,以及从第二个可迭代对象中获得元素等。

尝试一下以更好地感受它,例如:

list(product([1, 2], [3, 4])) == [(1, 3), (1, 4), (2, 3), (2, 4)]

如果您将可迭代对象的产品与自身一起使用,则会发生同样的情况,例如:

list(product('AB', 'AB')) == [('A', 'A'), ('A', 'B'), ('B', 'A'), ('B', 'B')]

请注意,我一直在调用product()list() ,这是因为product()返回一个生成器并将生成器传递给list()将生成器耗尽到一个列表中,以便打印。

product()的最后一步是你还可以给它一个可选的repeat参数,它告诉product()做同样的事情,但只是重复 iterable 一定次数。 例如:

list(product('AB', repeat=2)) == [('A', 'A'), ('A', 'B'), ('B', 'A'), ('B', 'B')]

因此,您可以看到调用product(xs, repeat=n)将如何生成您之后的所有序列,如果您从n=1开始并一直用尽它以获得更大的n

最后, yield from是一种在您自己的生成器中一次从另一个生成器生成结果的方法。 例如, yield from some_gen与:

for x in some_gen:
    yield x

所以, yield from (product(xs, repeat=n))等同于:

for p in (product(xs, repeat=n)):
    yield p

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM