Project 1: The Game of Hog--Problem 8 (2 pt)问题
在写def make_averaged(original_function, samples_count=1000):
函数的时候,发现函数很容易实现,但是加入实际的情景就没法理解。现在在这里记录下自己遇到的问题:
Problem 8 (2 pt)问题描述
Implement
make_averaged
, which is a higher-order function that takes a functionoriginal_function
as an argument.The return value of
make_averaged
is a function that takes in the same number of arguments asoriginal_function
. When we call this returned function on the arguments, it will return the average value of repeatedly callingoriginal_function
on the arguments passed in.Specifically, this function should call
original_function
a total ofsamples_count
times and return the average of the results of these calls.
问题解析
这个问题其实很简单。make_averaged
函数接受两个参数:
original_function
:接受n个参数,返回一个值samples_count
:重复调用函数A的次数
接受了两个入参后,返回一个函数(高阶函数,将函数作为返回值)。这个函数接受的参数与original_function
接受的参数相同。调用这个新函数的时候,会返回重复调用samples_count
次original_function
的值。
疑问
但是在检测自己是否理解这个函数(python3 ok -q 08 -u
)的选项中,对于这个问题我总是答错:
>>> from hog import * >>> dice = make_test_dice(3, 1, 5, 6) >>> averaged_roll_dice = make_averaged(roll_dice, 1000) >>> # Average of calling roll_dice 1000 times >>> # Enter a float (e.g. 1.0) instead of an integer >>> averaged_roll_dice(2, dice) ?
在我理解中,dice
被定义好后,每次调用dice
就会指定下一个值,然后循环如此。(这个坑好久之前就被埋好了😒 )
roll_dice
呢,就是一个函数,接收投掷总数和骰子类型,返回投多个骰子的总点数(遵循sow sad原则)。
那么既然说这个make_averaged
函数是重复调用samples_count
次original_function
的值,那么就先看看在这里调用一次original_function
的效果,然后看看重复调用samples_count
的效果。
roll_dice(2, dice)
:这个函数就是make_averaged
参数1。这个函数投掷两次骰子,然后算总和。例如第一次投掷两枚骰子,结果分别为3和1,符合“sow sad”原则,所以这次结果为1。- 重复调用
samples_count
次的结果:这就是我卡住的地方,也是需要反思的地方。
解决思路
这里因为我并没有深入理解dice
函数的机制,导致我并不理解重复调用dice
到底有什么效果。下面贴上dice
的代码,学习一下嵌套函数如何利用nonlocal
将修改上一层函数的变量:
def make_test_dice(*outcomes): """Return a die that cycles deterministically through OUTCOMES. >>> dice = make_test_dice(1, 2, 3) >>> dice() 1 >>> dice() 2 >>> dice() 3 >>> dice() 1 >>> dice() 2 This function uses Python syntax/techniques not yet covered in this course. The best way to understand it is by reading the documentation and examples. """ assert len(outcomes) > 0, 'You must supply outcomes to make_test_dice' for o in outcomes: assert type(o) == int and o >= 1, 'Outcome is not a positive integer' index = len(outcomes) - 1 def dice(): nonlocal index index = (index + 1) % len(outcomes) return outcomes[index] return dice
这里的dice()
函数中,使用nonlocal index
的声明,dice()
可以修改make_test_dice
的局部变量index
。
这样代码就好理解了:
>>> dice = make_test_dice(3, 1, 5, 6)
dice
每次调用的时候,都会改变make_test_dice
的局部变量index
。这样index
就会循环往复地在[0, len(outcomes) - 1]
中徘徊。
使用 nonlocal
关键字可以指示 Python 解释器在嵌套函数中查找并修改上一层函数的局部变量。
这样再去看roll_dice(2, dice)
重复调用samples_count
次的结果:第一次投掷两个骰子,结果分别为3和1,得分为1;第二次投掷两个骰子,结果分别为5和6,得分为11;第三次投掷两个骰子,结果分别为3和1,得分为1...
这样重复调用的结果就是1和11,重复1000次的平均值就是(1 * 500 +11 * 500) / 1000 = 6.0。
总结
- 请读源码:调用函数解决问题前,需要详细理解每一个函数到底做了什么。
- 遇到问题:那肯定是你代码没弄明白又或者是出现了bug,请再次重新回顾代码,做到详尽理解和测试。
- 偷懒被教育:
nonlocal
关键字懒得查,注释This function uses Python syntax/techniques not yet covered in this course. The best way to understand it is by reading the documentation and examples.
也懒得理解,最终导致了让我跌了个跟头。而这个坑又是自信的我亲手埋下的。
本文作者:上山砍大树
本文链接:https://www.cnblogs.com/shangshankandashu/articles/18021986
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步