选择受其位置影响的列表中的随机元素

时间:2014-06-17 04:57:06

标签: python python-3.x random

我有一个包含四个元素的列表,并选择其中一个最大化我执行此操作的第一个元素的机会:

from random import choice
_list = [19,14,29,3]
element = choice((a[0],a[0],a[0],a[0],a[1],a[1],a[1],a[2],a[2],a[3]))

虽然现在_list中的元素数量是可变的,但在编写此片段之前尝试保留相同的行为:

from random import choice
_list = [19,14,29,3,.......] # n elements
weighted = []
for i in range(len(_list)):
    for j in range(len(_list)-i):
        weighted.append(_list[i])
element = choice(weighted)

是否有其他方法可以用更少的代码实现相同的结果并且效率更高?因为我认为如果n变得太大,那么weighted将是巨大的并且会减慢我的算法。

2 个答案:

答案 0 :(得分:2)

实际上有一个内置函数可以帮到你:

random.triangular(0, length, 0)

Here's the documentation for that function

如果您想自己编写,实际上可以在不使用任何循环的情况下执行此操作。如果你正确看待它,很容易看出来。例如,对于6个元素,您可以将其可视化为:

|
| |
| | |
| | | |
| | | | |
| | | | | |
0 1 2 3 4 5

如果我们将它翻转并将其重新组合在一起,我们就可以得到一个矩形:

5 4 3 2 1 0
| | | | | |
- | | | | |
| - | | | |
| | - | | |
| | | - | |
| | | | - |
| | | | | -
| | | | | |
0 1 2 3 4 5

对于长度为6的列表,矩形的高度为7,宽度为6.因此,您只需要选择两个随机整数并找出该坐标所属的数字。这可以通过简单的计算完成 - 断裂正下方的所有坐标都有x + y等于n-1,而断裂正上方的所有坐标都有x + y等于n。不用多说,这里是代码:

def triangle_random(count):
    x = random.randint(0, count-1) # randint includes both ends, so we need count-1
    y = random.randint(0, count)
    if x + y < count:
        return x
    else:
        return count-1 - x

答案 1 :(得分:0)

@RobWatts通过使用几何体给出了一个很好的答案,但我也找到了另一种有效获得相同结果的方法:

import random
_list = [1,2,3,4]
S = (len(_list)+1)*len(_list)/2 # This represents the Sum of what would be the 'weighted' list composed by elements following a(0) = 1 and a(n) = a(n-1)+1 conditions
x = random.randint(1,S) # pick one element from what would be 'weighted' list 
last = 0
for i in range(len(_list)): # get which element in _list 'x' points out
    if( x <= len(_list)-i+last ): # first 'len(_list)' elements point out to _list[0], then the next len(_list)-1 elements to _list[1] and so on
        element1 = _list[i]
        break
    else: last += len(_list)-i