回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我希望能够获取一个数字范围,并返回一个包含三元组且没有重复项的列表。x的每个元素应该在三元组的每个位置出现一次。目标是得到如下信息:</p>
<pre><code>get_combinations_without_duplicates(3) = [(0, 1, 2), (1, 2, 0), (2, 0, 1)]
</code></pre>
<p>对于范围(3),这只是一个列表旋转,但是对于更高的范围,有更多可能的组合。我希望能够随机生成满足这些约束的三元组列表。</p>
<p>假设我们首先为n=4的情况指定每个三元组的第一个元素:</p>
<p>[(0,),(1,),(2,),(3,)]</p>
<p>第一个三元组的第二个元素可以不是0。一旦选择了其中一个,就限制了下一个三元组的选项,以此类推。我们的目标是有一个函数,它接受一个数字,并以这种方式创建三元组,但并不总是创建相同的三元组。也就是说,最终结果可能是轮换:</p>
<pre><code>[(0, 1, 2), (1, 2, 3), (2, 3, 0), (3, 0, 1),]
</code></pre>
<p>或者</p>
<pre><code>[(0, 2, 3), (1, 3, 0), (2, 0, 1), (3, 1, 2)]
</code></pre>
<p>以下是此功能的实现:</p>
<pre><code>def get_combinations_without_duplicates(n):
output = []
second = range(n)
third = range(n)
for i in range(n):
triple = [i]
#Get the second value of the triple, but make sure that it isn't a
#duplicate of the first value
#in the triple or any value that has appeared in the second position of any triple
choices_for_second = [number for number in second if number not in triple]
#Randomly select a number from the allowed possibilities
n_second = random.choice(choices_for_second)
#<a href="https://www.cnpython.com/list/append" class="inner-link">append</a> it to the triple
triple.append(n_second)
#Remove that value from second so that it won't be chosen for other triples
second = [number for number in second if number != n_second]
#Do the same for the third value
choices_for_third = [number for number in third if number not in triple]
n_third = random.choice(choices_for_third)
triple.append(n_third)
third = [number for number in third if number != n_third]
output.append(tuple(triple))
return output
</code></pre>
<p>正如下面指出的,这个过程有时会随机选择不起作用的组合。如果你做了如下的事情就可以处理:</p>
<pre><code>def keep_trying(n):
try:
return get_combinations_without_duplicates(n)
except IndexError:
return keep_trying(n)
</code></pre>
<p>但是,我想知道是否有更好的方法来做这件事。</p>