问题描述
我从整数列表开始:
A = [1,2, 5,3,4 ,6,7,8]
洗牌后,我希望某些元素(例如3、4和5)保留它们在A中的出现顺序,而其余元素可以自由地随机洗牌。像这样:
结果1: A = [ 5 ,2, 3 ,1、8, 4 ,6、7]
-或-
结果2: A = [7, 5 ,6,1, 3 , 4 ,8,2]
-但不是-
结果3(无效结果) A = [7, 4 ,6,1, 3 , 5 ,8,2]
感谢所有建议!
解决方法
提取要保持相对顺序的元素,像往常一样随机播放,然后通过随机选择要插入的“保留”元素的索引将列表重新粘在一起。如果您使用集合来加速in
操作,那么所有操作都是线性的,而我并不在意。 keep
列表的顺序很重要。
>>> import random
>>> L = [1,2,5,3,4,6,7,8]
>>> keep = [2,4]
>>> kept = [L[i] for i in keep][::-1]
>>> unkept = [x for i,x in enumerate(L) if i not in keep]
>>> random.shuffle(unkept)
>>> idxes = random.sample(list(range(len(L))),k=len(keep))
>>> result = [kept.pop() if i in idxes else unkept.pop() for i in range(len(L))]
>>> result
[6,8,1,2]
随机测试:
import random
def shuffle_with_fixed_order(L,keep):
kept = [L[i] for i in keep][::-1]
unkept = [x for i,x in enumerate(L) if i not in keep]
random.shuffle(unkept)
idxes = random.sample(list(range(len(L))),k=len(keep))
return [kept.pop() if i in idxes else unkept.pop() for i in range(len(L))]
if __name__ == "__main__":
for _ in range(5000):
L = list(range(50))
random.shuffle(L)
keep = sorted(random.sample(L,k=20))
shuffled = shuffle_with_fixed_order(L,keep)
new_locs = [shuffled.index(L[i]) for i in keep]
assert all(x < y for x,y in zip(new_locs,new_locs[1:]))
,
这是使用random
模块的一种方法
例如:
import random
A = [ 1,8 ]
result = A[2:5]
del A[2:5]
while A:
l = len(A)
result.insert(random.randint(0,l),A.pop(random.randrange(l)))
print(result)
演示
def rand_shfl(lst):
result = lst[2:5]
del lst[2:5]
while A:
l = len(A)
result.insert(random.randint(0,A.pop(random.randrange(l)))
return result
for _ in range(10):
A = [ 1,8 ]
print((rand_shfl(A)))
输出:
[1,2]
[8,4]
[8,4]
[1,6]
[6,2]
[7,8]
[1,7]
[5,2]
[1,6]
[8,1]
,
以下可能适合您
import random
lst=[1,8]
s_lst = {5:0,3:0,4:0}
idx_lst = [random.randint(0,len(lst)) for i in range(len(s_lst))]
idx_lst.sort()
for i,s in enumerate(s_lst.keys()):
s_lst[s] = idx_lst[i]
lst.remove(s)
random.shuffle(lst)
for k,v in s_lst.items():
lst.insert(v,k)
print(lst)