给定一个可迭代的,如何在每个可能的组合中应用函数?

时间:2013-12-15 09:46:55

标签: python

鉴于可迭代[A, B, C]和函数f(x),我希望得到以下内容:

[  A,     B,     C]  
[  A,     B,   f(C)]  
[  A,   f(B),    C]
[  A,   f(B),  f(C)]
[f(A),    B,     C]
[f(A),    B,   f(C)]
[f(A),  f(B),    C]
[f(A),  f(B),  f(C)]

不幸的是我在itertools模块中找不到合适的东西。

3 个答案:

答案 0 :(得分:9)

>>> from itertools import product
>>> L = ["A", "B", "C"]
>>> def f(c): return c.lower()
... 
>>> fL = [f(x) for x in L]
>>> for i in product(*zip(L, fL)):
...     print i
... 
('A', 'B', 'C')
('A', 'B', 'c')
('A', 'b', 'C')
('A', 'b', 'c')
('a', 'B', 'C')
('a', 'B', 'c')
('a', 'b', 'C')
('a', 'b', 'c')

说明:

f中的每个项目致电L以生成fL

>>> fL
['a', 'b', 'c']

使用zip将两个列表压缩成对

>>> zip(L, fL)
[('A', 'a'), ('B', 'b'), ('C', 'c')]

使用itertools.product

获取这些元组的笛卡尔积
product(*zip(L, fL))

相当于

product(*[('A', 'a'), ('B', 'b'), ('C', 'c')])

,这相当于

product(('A', 'a'), ('B', 'b'), ('C', 'c'))

循环遍历该产品,准确提供我们需要的结果。

答案 1 :(得分:1)

您可以使用itertools.combinations,就像这样

def f(char):
    return char.lower()

iterable = ["A", "B", "C"]
indices = range(len(iterable))
from itertools import combinations
for i in range(len(iterable) + 1):
    for items in combinations(indices, i):
        print [f(iterable[j]) if j in items else iterable[j] for j in range(len(iterable))]

<强>输出

['A', 'B', 'C']
['a', 'B', 'C']
['A', 'b', 'C']
['A', 'B', 'c']
['a', 'b', 'C']
['a', 'B', 'c']
['A', 'b', 'c']
['a', 'b', 'c']

答案 2 :(得分:1)

import itertools
def func_combinations(f, l):
    return itertools.product(*zip(l, map(f, l)))

演示:

>>> for combo in func_combinations(str, range(3)):
...     print combo
...
(0, 1, 2)
(0, 1, '2')
(0, '1', 2)
(0, '1', '2')
('0', 1, 2)
('0', 1, '2')
('0', '1', 2)
('0', '1', '2')

此函数首先为输入的每个元素计算f一次。然后,它使用zip将输入和f值列表转换为输入 - 输出对列表。最后,它使用itertools.product生成每种可能的方式来选择输入或输出。