用偏差随机排序一个列表

时间:2016-07-19 10:03:41

标签: python list sorting random

我有一份清单如下:

i = [
        {'id': '1', 'P': 0.5},
        {'id': '2', 'P': 0.4},
        {'id': '3', 'P': 0.8},
        ...
        {'id': 'x', 'P': P(x)}
    ]

当我执行以下操作时:

i.sort(key=lambda x: x['P'], reverse=True)

列表基于P排序,其中具有最大P的元素在前面。但是如果我想让它看起来是随机的,那么即使一个P值很小的元素(概率非常小)也可以作为列表中的第一个项目?
是否可以使用sort()函数实现它,或者我必须自己编写?

3 个答案:

答案 0 :(得分:3)

根据我的理解,您希望对列表进行排序,但仍需要一些随机性。列表不能同时排序和随机排序。最近的可以通过像

这样的东西来实现
i.sort(key=lambda x: x['P']*random.triangular(0.6, 1.4), reverse=True)

这同时确保订单不是完全随机的,也不是以类似的方式排序。

0.61.4可以根据您想要的偏差进行更改。

答案 1 :(得分:3)

正如我在评论中提到的那样,您可以通过从标准正态分布中采样偏差因子来对随机偏差进行排序。然后,您可以将此偏差(在零的任一侧对称)添加到P值。

import numpy as np

#Give some control over the level of rearrangement - larger equals more rearrangement
bias_factor = 0.5

i.sort(key=lambda x: x['P'] + np.random.randn()*bias_factor, reverse=True)

或者,如果您只想使用标准库:

from random import gauss

#Give some control over the level of rearrangement - larger equals more rearrangement
sigma = 0.5

i.sort(key=lambda x: x['P'] + gauss(0, sigma), reverse=True)

答案 2 :(得分:2)

以下是我的看法:假设第1项具有相似性得分 $loginUrl = $helper->getLoginUrl(array('email')); ,而第2项具有相似性得分0.3。然后,在这两个项目之间进行选择时,项目1应该在项目2之前,概率为0.4,这似乎是合理的。这样得分较高的项目通常是 之前得分较低的项目。以下函数实现了merge-sort的变体,它包含了这个想法:

0.3 / (0.3 + 0.4)

进行测试:

import random

def pick(a,b,key = None):
    ka = key(a) if key else a
    kb = key(b) if key else b
    if ka+kb == 0:
        return random.int(0,1)
    else:
        p = ka/(ka+kb)
        return 0 if random.random() <= p else 1

def randMerge(xs,ys,key = None):
    merged = []
    i = j = 0
    while i < len(xs) and j < len(ys):
        k = pick(xs[i],ys[j],key)
        if k == 0:
            merged.append(xs[i])
            i += 1
        else:
            merged.append(ys[j])
            j += 1
    if i == len(xs):
        merged.extend(ys[j:])
    else:
        merged.extend(xs[i:])
    return merged

def randSort(items,key = None):
    if len(items) < 2:
        return items
    else:
        n = len(items)//2
        xs = items[:n]
        ys = items[n:]
        return randMerge(randSort(xs,key),randSort(ys,key),key)

例如:

i = [
        {'id': '1', 'P': 0.5},
        {'id': '2', 'P': 0.4},
        {'id': '3', 'P': 0.8},
        {'id': '4', 'P': 0.9}
    ]