4.9 排列组�的迭代¶

问题¶

你想迭代�历一个集�中元素的所有�能的排列或组�

解决方案¶

itertools模��供了三个函数�解决这类问题。 其中一个是 itertools.permutations() , 它接�一个集�并产生一个元组�列,�个元组由集�中所有元素的一个�能排列组�。 也就是说通过打乱集�中元素排列顺�生�一个元组,比如:

>>> items = ['a', 'b', 'c']
>>> from itertools import permutations
>>> for p in permutations(items):
...     print(p)
...
('a', 'b', 'c')
('a', 'c', 'b')
('b', 'a', 'c')
('b', 'c', 'a')
('c', 'a', 'b')
('c', 'b', 'a')
>>>

如果你想得到指定长度的所有排列,你�以传递一个�选的长度�数。就�这样:

>>> for p in permutations(items, 2):
...     print(p)
...
('a', 'b')
('a', 'c')
('b', 'a')
('b', 'c')
('c', 'a')
('c', 'b')
>>>

使用 itertools.combinations() �得到输入集�中元素的所有的组�。比如:

>>> from itertools import combinations
>>> for c in combinations(items, 3):
...     print(c)
...
('a', 'b', 'c')

>>> for c in combinations(items, 2):
...     print(c)
...
('a', 'b')
('a', 'c')
('b', 'c')

>>> for c in combinations(items, 1):
...     print(c)
...
('a',)
('b',)
('c',)
>>>

对于 combinations() �讲,元素的顺�已����了。 也就是说,组� ('a', 'b') 跟 ('b', 'a') 其实是一样的(最终�会输出其中一个)。

在计算组�的时候,一旦元素被选�就会从候选中剔除掉(比如如果元素’a’已�被选�了,那么接下�就�会�考虑它了)。 而函数 itertools.combinations_with_replacement() �许�一个元素被选择多次,比如:

>>> for c in combinations_with_replacement(items, 3):
...     print(c)
...
('a', 'a', 'a')
('a', 'a', 'b')
('a', 'a', 'c')
('a', 'b', 'b')
('a', 'b', 'c')
('a', 'c', 'c')
('b', 'b', 'b')
('b', 'b', 'c')
('b', 'c', 'c')
('c', 'c', 'c')
>>>

讨论¶

这一�节我们�你展示的仅仅是 itertools 模�的一部分功能。 尽管你也�以自己手动实现排列组�算法,但是这样�得�花点脑力。 当我们碰到看上去有些��的迭代问题时,最好�以先去看看itertools模�。 如果这个问题很普�,那么很有�能会在里�找到解决方案�