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