Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有没有比这更好的方法从列表中随机选择:_Python_Python 3.x - Fatal编程技术网

Python 有没有比这更好的方法从列表中随机选择:

Python 有没有比这更好的方法从列表中随机选择:,python,python-3.x,Python,Python 3.x,如您所见,最有可能选择a,但有更好/更短的方法吗?如果您使用的是选项,而不是选项,则可以为每个元素指定权重 choices = [a,a,a,a,b,b,c] random.choice(choices) 第二个参数是第一个参数中每个元素的相对权重。例如,在下面的示例中,您可以看到a的选择频率大约是b的两倍,大约是c的四倍 random.choices([a,b,c], [4,2,1]) 如果您没有使用Python 3.6+(在random.choices中支持权重),则可以构建总体: &g

如您所见,最有可能选择a,但有更好/更短的方法吗?

如果您使用的是
选项
,而不是
选项
,则可以为每个元素指定权重

choices = [a,a,a,a,b,b,c]
random.choice(choices)
第二个参数是第一个参数中每个元素的相对权重。例如,在下面的示例中,您可以看到
a
的选择频率大约是
b
的两倍,大约是
c
的四倍

random.choices([a,b,c], [4,2,1])

如果您没有使用Python 3.6+(在
random.choices
中支持权重),则可以构建总体:

>>> import collections, random
>>> collections.Counter(random.choices('abc', [4,2,1], k=100))
Counter({'a': 58, 'b': 25, 'c': 17})
如果您担心较大权重值的性能,可以使用
itertools.accumulate
bisect

import random
a, b, c = 'abc'

weighted = [(a, 4), (b, 2), (c, 1)]

population = [x for x, weight in weighted for _ in range(weight)]
random.choice(population)

你的意思是从
[a,b,c]
中选择,但不统一?这种方式有什么不对?你说的“更好”是什么意思?Idk说我想打印一个随机选择,但得到a的机会比得到b或b的机会多c@juanpa.arrivillaga如果有很多选择的话,时间很长。我所说的更好是指做同样事情的代码更少如果你定义权重,这怎么会更随机呢?
随机。选择(“abc”)
将有1/3的机会返回
a
b
,或
c
<代码>随机。选择('abc',[4,2,1])将选择
a
7次中的4次,
b
7次中的2次,以及
c
7次中的1次。它仍然是随机的,但不是均匀分布。@darshvader,因为其中一个更可能是随机分布chosen@chepner好的,很好的解释。出于某种原因,我忘记了即使是随机的,它们仍然会一致对齐。@chepner的功能与我最初使用的相同?这与OP使用的功能完全相同。@Austin的重点是避免键入
a、a、a、a、a、a、a、a、a、a、
。。。对于较大的值。@准确地说是Tomothy32,谢谢。我认为这是显而易见的,如果重量很大,这将是非常低效的。@Ekhumaro我补充了一个更一般的方法,尽管它使事情变得非常复杂。
import bisect
import itertools
import random

choices = ['a', 'b', 'c']
weights = [4, 2, 1]
cumulative_weights = list(itertools.accumulate(weights))

print(choices[bisect.bisect(cumulative_weights, random.random() * cumulative_weights[-1])])