【问题标题】:How to randomize the order of elements of a list while making sure no consecutive values are equal?如何在确保没有连续值相等的同时随机化列表元素的顺序?
【发布时间】:2014-04-09 12:24:37
【问题描述】:

我有一个 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)

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

谢谢。

【问题讨论】:

  • 你可以shuffle 然后乘以random.shuffle(elems); ans = 2*elems。还是不够随机?
  • 输入列表中的元素是否不同?

标签: python algorithm list sorting random


【解决方案1】:

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

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']

【讨论】:

    【解决方案2】:

    您可以创建一个函数来检查列表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() 可以继续生成其中包含连续值的列表,但它最终会起作用 :)

    【讨论】:

    • 这可能会永远运行:)
    【解决方案3】:

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

    R 成为你的结果列表

    1. elems中选择一个随机元素e,并将e附加到R
    2. elems_1 = elems \ e,即从elems中删除e
    3. elems_1中选择一个随机元素e_1,并将e_1附加到R
    4. elems_1 = elems \ e_1,即从elems中删除e_1
    5. 从第 3 步开始重复,直到 R 足够长

    【讨论】:

      【解决方案4】:

      我认为这会起作用,虽然它不是那么优雅。

      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 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-30
        • 1970-01-01
        • 2016-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-29
        • 1970-01-01
        相关资源
        最近更新 更多