如何在确保没有连续值相等的情况下随机化列表元素的顺序?

时间:2014-04-09 12:24:38

标签: python algorithm list sorting random

我有一个字符串的python列表,让我们说:

elems = ["A", "B", "C", "D"]

我想创建一个新列表,其元素是elems的每个元素重复固定次数(让我们说两次),以随机顺序,但同时确保两个连续元素从来没有相同的价值。

例如,["D", "B", "A", "B", "D", "C", "A", "C"]是一个很好的结果。 ["D", "B", "A", "B", "D", "C", "C", "A"]不是(C在第6和第7位重复)。

最简单的想法只是:

ans = 2*elems
random.shuffle(ans)

然后是一些代码来处理重复,但我能想到的所有解决方案都涉及潜在的无限循环。有没有一种简单可靠的方法呢?

感谢。

4 个答案:

答案 0 :(得分:6)

我假设输入列表具有不同的元素。

import random

def randomize_carefully(elems, n_repeat=2):
    s = set(elems)
    res = []
    for n in range(n_repeat):
        if res:
            # Avoid the last placed element
            lst = list(s.difference({res[-1]}))
            # Shuffle
            random.shuffle(lst)
            lst.append(res[-1])
            # Shuffle once more to avoid obvious repeating patterns in the last position
            lst[1:] = random.sample(lst[1:], len(lst)-1)
        else:
            lst = elems[:]
            random.shuffle(lst)
        res.extend(lst)
    return res

for i in range(10):
    print randomize_carefully(["A", "B", "C", "D"])

一些输出:

['B', 'C', 'D', 'A', 'C', 'A', 'D', 'B']
['B', 'D', 'C', 'A', 'C', 'B', 'A', 'D']
['C', 'B', 'D', 'A', 'B', 'C', 'D', 'A']
['B', 'D', 'A', 'C', 'A', 'B', 'D', 'C']
['D', 'C', 'A', 'B', 'C', 'D', 'A', 'B']
['C', 'D', 'A', 'B', 'D', 'C', 'A', 'B']
['D', 'A', 'C', 'B', 'C', 'A', 'B', 'D']
['C', 'D', 'A', 'B', 'C', 'D', 'A', 'B']
['C', 'B', 'A', 'D', 'A', 'B', 'D', 'C']
['B', 'D', 'A', 'C', 'A', 'D', 'C', 'B']

答案 1 :(得分:1)

您可以创建一个函数来检查列表x中的两个连续值是否相同:

def compareConsecutive(x):
    for i in x:
        if i == x[x.index(i)+1]:
            return False

然后在while循环中随机播放列表,直到compareConsecutive()停止返回False

while compareConsecutive(ans) == False:
    random.shuffle(ans)

这可能需要一段时间才能显示长列表,因为random.shuffle()可以继续生成包含连续值的列表,但最终会有效:)

答案 2 :(得分:0)

我认为这可能是一种做你想做的算法:

R成为您的结果列表

  1. e中选择一个随机元素elems,然后将e追加到R
  2. 允许elems_1 = elems \ e,即从e
  3. 中移除elems
  4. e_1中选择一个随机元素elems_1,然后将e_1追加到R
  5. 允许elems_1 = elems \ e_1,即从e_1
  6. 中移除elems
  7. 从步骤3开始重复,直到R足够长

答案 3 :(得分:0)

我认为这会奏效,虽然它不那么优雅。

import random

elems = ['a','b','c','d']
length = len(elems)

l = []

for i in range(2):
    random.shuffle(elems)
    l.extend( elems )
    if i > 0 and l[ i*length ] == l[ i*length - 1 ]:
        l[i*length-2], l[i*length-1] = l[i*length-1], l[i*length-2]

print l