在采访中,我遇到了以下我不知道的编码问题。从那时起,我一直在思考它,而且似乎无法弄清楚如何编写一个在给定的时间百分比内返回值的函数。
问题如下:
假设您有字典dict = {'A':10,'B':30,'C':60}。编写一个函数,该函数在10%的时间内返回“ A”,在30%的时间内返回“ B”,在60%的时间内返回“ C”。因此,该函数应以值作为数字的字典(它们不一定要相加100),并且应返回该值的键,该键的值与键占所有键之和的百分比相对应。
我对如何启动功能有个想法...
def percent_return(dict):
sum = 0
for key, value in dict.items():
sum += float(value)
percent_array = []
for key, value in dict.items():
percent = float(value) / sum
percent_array.append(percent)
''' We now have an array with the associated percentages for the dictionary,
but now I don't know how to actually apply this to the return values '''
for key, value in dict.items():
if (something that indicates given %):
return key
我对python还是很陌生,所以请原谅我的无知,并感谢您的帮助!
答案 0 :(得分:1)
您的代码有几个问题:
sum
和dict
内置组件。永远不要这样做。内置random.choice
已具有此功能。为了提高效率,您可以将sum
与dict.values
直接使用,并使用字典理解来计算权重。由于random.choices
返回一个列表,因此我们可以将next
与iter
一起使用,以提取唯一的元素。
from random import choices
d_weights = {'A': 10, 'B': 30, 'C': 60}
def percent_return(d):
val_sum = sum(d.values())
d_pct = {k: v/val_sum for k, v in d.items()}
return next(iter(choices(population=list(d_pct), weights=d_pct.values(), k=1)))
res = percent_return(d_weights)
答案 1 :(得分:0)
您可以使用random.randrange
在0和所有dict值之和之间绘制一个值,使用itertools.accumulate
从这些值生成一系列累加和,然后使用itertools.dropwhile
查找不小于平局的第一个累积和,并返回该索引处的字典键,并通过使用enumerate
返回累积和:
import random
from itertools import accumulate, dropwhile
def pick(d):
draw = random.randrange(sum(d.values()))
return list(d.keys())[next(dropwhile(lambda t: t[1] < draw, enumerate(accumulate(d.values()))))[0]]
这样:
from collections import Counter
d = {'A': 10, 'B': 30, 'C': 60}
print(Counter(pick(d) for _ in range(1000)))
可以输出:
Counter({'C': 587, 'B': 286, 'A': 127})
答案 2 :(得分:0)
可以吗? ...虽然我的代码会根据每个Key的“机会”将其打印出来,但是我不确定我是否理解这个问题。
from random import randint
example = {
'A': 10,
'B': 50,
'C': 80
}
def percent_return(dictionary):
for key, value in dictionary.items():
if randint(1, 100) < value:
yield key
for char in percent_return(example):
print(char)
答案 3 :(得分:0)
`random.choices *接受加权分配,不确定目标是打印还是存储计数,但可以通过这种方式完成
from random import choices
d = {'A': 10, 'B': 30, 'C': 60}
l = []
for i in range(sum([v for v in d.values()])):
l.append(*choices([k for k in d],[.1, .3, .6]))
print(l)
print({i: l.count(i) for i in [k for k in d]})
['C', 'C', 'B', 'C', 'C', 'C', 'C',..., 'C', 'C', 'B'] {'A': 8, 'B': 30, 'C': 62}