Python 函数 returns 一个值在一定百分比的时间内
Python function that returns a value a certain percent of the time
在一次面试中,我遇到了以下我无法理解的编码问题。从那时起我就一直在思考这个问题,但我似乎无法弄清楚如何编写一个 returns 在给定百分比的时间内返回一个值的函数。
题目如下:
Say you have a dictionary dict = {'A': 10, 'B': 30, 'C': 60}. Write a function that returns 'A' 10% of the time, 'B' 30% of the time, and 'C' 60% of the time. So, the function should take in a dictionary with values as numbers (they don't necessarily have to add up to 100), and it should return that value's key in correspondence with the percentage that key is to the sum of all the keys.
我知道如何启动该功能...
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 的新手,所以请原谅我的无知,感谢您的帮助!
您的代码存在几个问题:
- 您隐藏
sum
和 dict
内置函数。永远不要这样做。
- 您正确计算了一组百分比,但没有将它们链接到键。
- 没有从您的密钥中检索加权样本的逻辑。
内置的random.choice
已经有这个功能了。为了提高效率,可以直接使用sum
和dict.values
,并使用字典理解来计算权重。由于 random.choices
returns 是一个列表,我们可以使用 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)
你可以使用random.randrange
在0和所有dict值的总和之间绘制一个值,使用itertools.accumulate
从这些值生成一个累积和序列,然后使用itertools.dropwhile
寻找第一个不小于 draw 的累积和,以及 return 该索引处字典的键,伴随着使用 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})
难道是这个? ...我不确定我是否理解这个问题,尽管我的代码会根据它们的 "chance".
打印出每个键
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)
`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}
在一次面试中,我遇到了以下我无法理解的编码问题。从那时起我就一直在思考这个问题,但我似乎无法弄清楚如何编写一个 returns 在给定百分比的时间内返回一个值的函数。
题目如下:
Say you have a dictionary dict = {'A': 10, 'B': 30, 'C': 60}. Write a function that returns 'A' 10% of the time, 'B' 30% of the time, and 'C' 60% of the time. So, the function should take in a dictionary with values as numbers (they don't necessarily have to add up to 100), and it should return that value's key in correspondence with the percentage that key is to the sum of all the keys.
我知道如何启动该功能...
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 的新手,所以请原谅我的无知,感谢您的帮助!
您的代码存在几个问题:
- 您隐藏
sum
和dict
内置函数。永远不要这样做。 - 您正确计算了一组百分比,但没有将它们链接到键。
- 没有从您的密钥中检索加权样本的逻辑。
内置的random.choice
已经有这个功能了。为了提高效率,可以直接使用sum
和dict.values
,并使用字典理解来计算权重。由于 random.choices
returns 是一个列表,我们可以使用 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)
你可以使用random.randrange
在0和所有dict值的总和之间绘制一个值,使用itertools.accumulate
从这些值生成一个累积和序列,然后使用itertools.dropwhile
寻找第一个不小于 draw 的累积和,以及 return 该索引处字典的键,伴随着使用 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})
难道是这个? ...我不确定我是否理解这个问题,尽管我的代码会根据它们的 "chance".
打印出每个键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)
`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}