如何在python中轻轻地打乱列表 [英] How to lightly shuffle a list in python

查看:99
本文介绍了如何在python中轻轻地打乱列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,我想对列表进行洗牌,但只做一点点.比如说,我只想移动少量元素.有没有简单的方法来完成这项工作?

I have this issue where I would like to shuffle a list, but only do so slightly. Say, I want only a small number of elements to be moved. Is there a simple way to get this done?

现在我能想到的最好的方法是手工构建我自己的方法,但是有什么方法可以使用 random 库来为我做这件事吗?

Right now the best I can think of is building my own method be hand, but is there some way to use the random library to do this for me?

推荐答案

为了展示其中一些解决方案的作用,我发现多次运行蒙特卡罗算法并查看分布有帮助

to show what some of these solutions are doing I find it helps to run a monte-carlo algorithm many times and look at the distribution

首先是@meta4 解决方案的整理版本,因为它是最充实的:

first a tidied up version of @meta4's solution as it was the most fleshed out:

from random import randrange

def partial_shuffle(l, factor=5):
    n = len(l)
    for _ in range(factor):
        a, b = randrange(n), randrange(n)
        l[b], l[a] = l[a], l[b]

我们可以通过执行多次运行:

which we can run many times by doing:

import numpy as np

n = 8
orig = list(range(n))
occur = np.zeros((n, n), int)

for _ in range(100000):
    x = orig[:]
    partial_shuffle(x,1)
    occur[orig,x] += 1

如果我们将出现表打印为百分比,我们会得到:

if we print out the occurrences table as percentages we get:

[[33.5  9.6  9.5  9.4  9.4  9.6  9.5  9.5]
 [ 9.6 33.2  9.7  9.5  9.6  9.6  9.4  9.4]
 [ 9.5  9.6 33.2  9.5  9.6  9.5  9.6  9.5]
 [ 9.5  9.3  9.6 33.4  9.5  9.5  9.5  9.6]
 [ 9.4  9.6  9.4  9.6 33.3  9.5  9.7  9.5]
 [ 9.6  9.5  9.6  9.6  9.4 33.3  9.5  9.6]
 [ 9.4  9.7  9.5  9.5  9.5  9.6 33.2  9.7]
 [ 9.5  9.5  9.6  9.5  9.7  9.5  9.6 33.2]]

每一行代表项目移动到列的概率.在这种情况下(当 n=8 时)算法将倾向于将元素保留在大约 33% 的时间里,然后统一选择其余部分

each row represents the probability of the item moving to the column. in this case (when n=8) the algorithm will tend to leave elements where they were ~33% of the time, and then pick the remainder uniformly

然后我可以运行(整理)版本的 pjs 代码:

I can then run (a tidied up) version of pjs's code with:

from random import gauss

orderliness = 2

occur = np.zeros((n, n), int)

for _ in range(100000):
    x = sorted(orig, key=lambda i: gauss(i * orderliness, 1))
    occur[orig,x] += 1

给出非常不同的输出:

[[91.9  7.9  0.1  0.   0.   0.   0.   0. ]
 [ 7.9 84.1  7.8  0.1  0.   0.   0.   0. ]
 [ 0.1  7.8 84.1  7.9  0.1  0.   0.   0. ]
 [ 0.   0.1  7.9 84.1  7.7  0.1  0.   0. ]
 [ 0.   0.   0.1  7.7 84.2  7.8  0.1  0. ]
 [ 0.   0.   0.   0.1  7.9 84.2  7.7  0.1]
 [ 0.   0.   0.   0.   0.1  7.7 84.2  7.9]
 [ 0.   0.   0.   0.   0.   0.1  7.9 91.9]]

即项目往往保持接近他们开始的地方

i.e. items tend to remain close to where they started

这种表格非常适合检测分布中的偏差,上面似乎没有证据.但是,例如,使用 Artyom 的解决方案 (shuffle(x, lambda: random()/5)) 给出以下内容:

this sort of table is great at detecting bias in the distribution, which there doesn't seem to be evidence of above. but, for example, with Artyom's solution (shuffle(x, lambda: random() / 5)) gives the following:

[[  0.   37.4   0.    0.    0.   16.7  23.8  22.1]
 [  0.    0.  100.    0.    0.    0.    0.    0. ]
 [  0.    0.    0.  100.    0.    0.    0.    0. ]
 [  0.    0.    0.    0.  100.    0.    0.    0. ]
 [  1.7   0.    0.    0.    0.   83.3  11.9   3. ]
 [  9.    7.4   0.    0.    0.    0.   64.2  19.4]
 [ 26.7  17.9   0.    0.    0.    0.    0.   55.5]
 [ 62.6  37.4   0.    0.    0.    0.    0.    0. ]]

这可能不是 OP 想要的.对角线的高概率表示将数组旋转一个元素

which probably isn't what the OP wanted. the high probability off diagonal represents rotating the array by one element

这篇关于如何在python中轻轻地打乱列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆