2017-07-15 57 views
1

我想知道是否有产生以下组合/排列的itertools方式:Itertools函数生成唯一排列

list = ['x', 'o'] 

# when character 'x' is allowed to occupy 1 place with total places of 4: 

a = [['o','o','o','x'], 
    ['o','o','x','o'], 
    ['o','x','o','o'], 
    ['x','o','o','o']] 

# when character 'x' is allowed to occupy 2 places with total places of 4: 

b = [['o','o','x','x'], 
    ['o','x','x','o'], 
    ['x','x','o','o'], 
    ['x','o','x','o'], 
    ['o','x','o','x'], 
    ['x','o','o','x']] 

我想知道是否有办法做到这一点使用itertools.product或类似函数来实现这一点?

回答

3

itertools.permutations也接受字符串作为paramater:

from itertools import permutations 
>>> list(permutations("ooox")) 
[('o', 'o', 'o', 'x'), ('o', 'o', 'x', 'o'), ('o', 'o', 'o', 'x'), ('o', 'o', 'x', 'o'), ('o', 'x', 'o', 'o'), ('o', 'x', 'o', 'o'), ('o', 'o', 'o', 'x'), ('o', 'o', 'x', 'o'), ('o', 'o', 'o', 'x'), ('o', 'o', 'x', 'o'), ('o', 'x', 'o', 'o'), ('o', 'x', 'o', 'o'), ('o', 'o', 'o', 'x'), ('o', 'o', 'x', 'o'), ('o', 'o', 'o', 'x'), ('o', 'o', 'x', 'o'), ('o', 'x', 'o', 'o'), ('o', 'x', 'o', 'o'), ('x', 'o', 'o', 'o'), ('x', 'o', 'o', 'o'), ('x', 'o', 'o', 'o'), ('x', 'o', 'o', 'o'), ('x', 'o', 'o', 'o'), ('x', 'o', 'o', 'o')] 

>>> list(permutations("ooxx")) 
[('o', 'o', 'x', 'x'), ('o', 'o', 'x', 'x'), ('o', 'x', 'o', 'x'), ('o', 'x', 'x', 'o'), ('o', 'x', 'o', 'x'), ('o', 'x', 'x', 'o'), ('o', 'o', 'x', 'x'), ('o', 'o', 'x', 'x'), ('o', 'x', 'o', 'x'), ('o', 'x', 'x', 'o'), ('o', 'x', 'o', 'x'), ('o', 'x', 'x', 'o'), ('x', 'o', 'o', 'x'), ('x', 'o', 'x', 'o'), ('x', 'o', 'o', 'x'), ('x', 'o', 'x', 'o'), ('x', 'x', 'o', 'o'), ('x', 'x', 'o', 'o'), ('x', 'o', 'o', 'x'), ('x', 'o', 'x', 'o'), ('x', 'o', 'o', 'x'), ('x', 'o', 'x', 'o'), ('x', 'x', 'o', 'o'), ('x', 'x', 'o', 'o')] 

将它们存储在一个列表的列表,如图你的问题,你可以使用map(list, permutations("ooox"))

正如您在评论部分中提到的那样,我们可以为该作业编写一个特定的函数,该函数接受您想要的输入,但注意当第一个字符串不是长度为1时,

from itertools import permutations 
def iterate(lst, length, places): 
    return set(permutations(lst[0]*(length-places)+lst[1]*places)) 

演示:

>>> from pprint import pprint 
>>> pprint(iterate(["o","x"], 4, 1)) 
{('o', 'o', 'o', 'x'), 
('o', 'o', 'x', 'o'), 
('o', 'x', 'o', 'o'), 
('x', 'o', 'o', 'o')} 
>>> pprint(iterate(["o","x"], 4, 2)) 
{('o', 'o', 'x', 'x'), 
('o', 'x', 'o', 'x'), 
('o', 'x', 'x', 'o'), 
('x', 'o', 'o', 'x'), 
('x', 'o', 'x', 'o'), 
('x', 'x', 'o', 'o')} 
+0

您的答案似乎有很多重复的内容。我们可以采取独特的,但我正在寻找一个函数,我可以指定地点的数量(在这个例子中是4)和一个元素X可以占据的地方的数量(在这个例子中,我给出了两个例子,1和2) – kPow989

+0

我不认为'itertools'对这个*精确*问题有特殊的功能。但是,编写一个函数需要一个长度为2的列表,所需的大小和空间并使用我显示的行来输出列表并不难。但我想这将是非常具体的。 –

+0

@ user3063482请检查我的编辑。 –

2

基于itertools.combinations你可以创建自己的函数(或发电机):

from itertools import combinations 

def equivalence_permutations(x, o): 
    """Create all unique permutations with `x` x'es and `o` o's.""" 
    total = x+o 
    for indices in combinations(range(total), x): 
     lst = ['o']*total 
     for index in indices: 
      lst[index] = 'x' 
     yield lst 

combinations确保索引是唯一的,无需使用set或任何其他贪婪操作。所以在这些情况下它应该快得多。例如:

>>> list(equivalence_permutations(2, 2)) # 2 x and 2 o 
[['x', 'x', 'o', 'o'], 
['x', 'o', 'x', 'o'], 
['x', 'o', 'o', 'x'], 
['o', 'x', 'x', 'o'], 
['o', 'x', 'o', 'x'], 
['o', 'o', 'x', 'x']] 

>>> list(equivalence_permutations(1, 3)) # 1 x and 3 o 
[['x', 'o', 'o', 'o'], 
['o', 'x', 'o', 'o'], 
['o', 'o', 'x', 'o'], 
['o', 'o', 'o', 'x']]