用python重复生成排列

我知道itertools,但它似乎只能生成排列而不重复。

例如,我想生成所有可能的骰子掷2个骰子。 所以我需要[1,2,3,4,5,6]的大小2的所有排列,包括重复:(1,1),(1,2),(2,1)…等

如果可能的话,我不想从头开始实施

您正在寻找笛卡尔积 。

在math中,笛卡儿积(或产品组)是两套产品的直接产品。

在你的情况下,这将是{1, 2, 3, 4, 5, 6} × {1, 2, 3, 4, 5, 6}itertools可以帮助你:

 import itertools x = [1, 2, 3, 4, 5, 6] [p for p in itertools.product(x, repeat=2)] [(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5), (3, 6), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5), (4, 6), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5), (5, 6), (6, 1), (6, 2), (6, 3), (6, 4), (6, 5), (6, 6)] 

要得到一个随机掷骰子(以一种完全没有效率的方式):

 import random random.choice([p for p in itertools.product(x, repeat=2)]) (6, 3) 

你不是在寻找排列 – 你需要笛卡尔积 。 对于这个使用itertools的产品 :

 from itertools import product for roll in product([1, 2, 3, 4, 5, 6], repeat = 2): print(roll) 

在Python 2.7和3.1中,有一个itertools.combinations_with_replacement函数:

 >>> list(itertools.combinations_with_replacement([1, 2, 3, 4, 5, 6], 2)) [(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6), (3, 3), (3, 4), (3, 5), (3, 6), (4, 4), (4, 5), (4, 6), (5, 5), (5, 6), (6, 6)] 

首先,你需要将由itertools.permutations(list)返回的生成器首先转换成列表。 然后,其次,你可以使用set()来删除重复项如下所示:

 def permutate(a_list): import itertools return set(list(itertools.permutations(a_list))) 

这里是C#版本(即使它的Python要求,algorithm应该是相同的)仅供参考:

下面的方法基本上没有。 骰子的时间可以扔到不同的排列。 对于上述问题,大小应该是“2”。

 private void GetAllPermutationsOfDice_Recursive(int size, string currentValue, List<string> values) { if(currentValue.Length == size) { values.Add(currentValue); return; } for(int i = 1; i<=6;i++) { this.GetAllPermutationsOfDice_Recursive(size, currentValue + i, values); } } 

掷骰子两次,上面的方法可以被称为:

 public string[] GetAllPermutationsOfDiceOfSize_2() { List<string> values = new List<string>(); this.GetAllPermutationsOfDice_Recursive(2, "", values); return values.ToArray(); } 

以下是相应的unit testing:

 [TestMethod] public void Dice_PermutationsTests() { var v = this.GetAllPermutationsOfDiceOfSize_2(); Assert.AreEqual(36, v.Length); int l = 6; List<string> values = new List<string>(); for(int i = 1; i<=4; i++) { values.Clear(); this.GetAllPermutationsOfDice_Recursive(i, "", values); Assert.AreEqual(l, values.Count); l *= 6; } }