繁体   English   中英

如何改组python列表以保留某些元素的出现?

[英]How to shuffle a python list such that the occurrence of some elements are preserved?

我从一个整数列表开始:

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, 3, 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, 5, 3, 8, 4, 1, 7, 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, 2, 5, 3, 4, 6, 7, 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, l), A.pop(random.randrange(l)))
    return result

for _ in range(10):
    A = [ 1, 2, 5, 3, 4, 6, 7, 8 ]
    print((rand_shfl(A)))

输出:

[1, 7, 6, 5, 8, 3, 4, 2]
[8, 1, 2, 7, 5, 3, 6, 4]
[8, 6, 7, 2, 1, 5, 3, 4]
[1, 7, 2, 8, 5, 3, 4, 6]
[6, 8, 7, 5, 1, 3, 4, 2]
[7, 2, 5, 6, 1, 3, 4, 8]
[1, 8, 5, 2, 3, 4, 6, 7]
[5, 7, 1, 6, 3, 8, 4, 2]
[1, 5, 7, 3, 2, 4, 8, 6]
[8, 2, 7, 6, 5, 3, 4, 1]

可能下面会为你工作

import random
lst=[1, 2, 5, 3, 4, 6, 7, 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM