我有一个字符串的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)
然后是一些代码来处理重复,但我能想到的所有解决方案都涉及潜在的无限循环。有没有一种简单可靠的方法呢?
感谢。
答案 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
成为您的结果列表
e
中选择一个随机元素elems
,然后将e
追加到R
elems_1 = elems \ e
,即从e
elems
e_1
中选择一个随机元素elems_1
,然后将e_1
追加到R
elems_1 = elems \ e_1
,即从e_1
elems
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