任何方法编写一个功能上等同于而不包含循环的函数?
Python代码:
luck = 0.3
tries = 200000000
getStrikes():
strikes = 0
for i in range(tries):
if random.random() <= luck:
strikes++;
return strikes
好的,抱歉我在过去5分钟内编辑过原始帖子的垃圾邮件。我现在就停止了,因为我根据收到的反馈澄清了我想问的内容。
答案 0 :(得分:3)
strikes
是binomial distribution的随机变量。 scipy
支持从此分布中抽样,而不是总计大量Bernouilli trials。
以下是一个例子:
from scipy.stats import binom
luck = 0.3
trials = 200000000
print binom(trials, luck).rvs()
尽管进行了大量试验,但这几乎是立即进行的。
答案 1 :(得分:2)
在函数式编程中有几种工具,比如折叠和列表/生成器理解,但最基本的想法是递归。
因此,例如,对于getTotal():
getTotal(sides, dice):
if dice == 0:
return 0
else
return rand.int(sides) + getTotal(sides, dice - 1)
遗憾的是,这个函数对你的具体例子不起作用,因为堆栈会在我们结束之前很久就会溢出。我们通过使函数tail递归来解决这个问题,因此您可以使用tail call optimization(并非所有语言都使用此功能,但几乎所有函数语言都使用此功能)。这是通过添加一个以0开头的累加器变量来实现的:
getTotal(sides, dice, accumulator = 0):
if dice == 0:
return accumulator
else
return getTotal(sides, dice - 1, accumulator + rand.int(sides))
在这个版本的函数中,递归调用是一个&#34;尾调用&#34;,这意味着它是该函数最后的事情(在以前的版本中不是这种情况) ,添加是最后发生的事情,所以它不是尾递归)。 getSixes()
版本可以用相同的方式完成,除了不仅仅是将骰子卷添加到累加器,当且仅当卷是累加器的6时,我们才加1。
然而,这种模式很常见,许多语言都有&#34;快捷方式&#34;为此,即fold。由于我不想发明一堆符号,我只想在Python中编写下一个例子:
def getTotal(sides, dice):
add = lambda x,y: x + y
return reduce(add, (rand.int(sides) for _ in range(dice)))
reduce
是左侧折叠的python名称,add
是我们正在折叠的函数。 (rand.int(sides) for _ in range(dice))
部分是一个懒惰的生成器(即我们需要它们,而不是一开始就是一次)生成随机数,特别是dice
个数。
函数式编程的另一个技巧是&#34; filter&#34;基于某些布尔函数的值。我们可以通过这种方式解决getSixes()
:
def getSixes(sides, dice):
condition = lambda x: x == 6
return len(filter(condition, (rand.int(sides) for _ in range(dice))))
所有这些方式都具有与使用循环相同的内存/速度特性(即,相同的大O特性),尽管使用循环通常更快一些,因为开销更少。
编辑:此答案更适用于您编辑之前的问题版本,但这个想法与您的新版本非常相似。
编辑2:原始标题是&#34;如何在不使用循环的情况下重写此问题&#34;这是我的答案所适用的,如何在不使用循环的情况下执行此操作。我没有意识到你想要一个数学公式,为什么我的答案根本不适用。