如何重新整理python列表,以便保留某些元素的出现?

问题描述

我从整数列表开始:

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)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...