鱼C论坛

 找回密码
 立即注册
查看: 3397|回复: 6

[已解决]新手的py程序报错了...绞尽脑汁还是不会改,求大佬指点一下如何修复

[复制链接]
发表于 2020-9-8 00:35:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
程序目标:传送门  小甲鱼Python课后作业动动手第0题

我的程序: 搜狗截图20年09月08日0026_1.png

文字版:
  1. #以上一长串为string1

  2. #利用刚学的闭包函数,再用a()连续读取出每一个字符
  3. def yihao():
  4.     i = 0
  5.     def erhao():
  6.         nonlocal i
  7.         result = string1[i]
  8.         i += 1
  9.         return result
  10.     return erhao
  11. a = yihao()

  12. #先设置好变量,列表
  13. t = 0
  14. zifu = []
  15. cishu = []

  16. #利用while循环,把所有的字符列成一个列表:zifu
  17. #再把字符出现的次数列成一个列表:cishu
  18. while t < len(string1):
  19.     if a() not in zifu:
  20.         zifu.append(string1[t])
  21.         cishu.append(string1.count(a()))
  22.     t += 1

  23. #利用for循环,打印出结果
  24. for each in zifu:
  25.     print(each,'一共出现了',cishu[zifu.index(each)],'次')
复制代码


报错内容: 搜狗截图20年09月08日0027_1.png
最佳答案
2020-9-8 09:26:41
错误原因:在第22行和第24行分别执行了 a() ,相当于每次 while 循环,a() 执行了两次,也就是跳过两个字符,所以 while 循环执行到一半的时候,a()就已经达到 string1 的结尾了
帮你把 while 这里修改了,下面这种写法是3.8以前的版本写法。3.8版本之后出现了 海象赋值(:=),也就是2楼所写的那样,就可以少写一行了。

  1. while t < len(string1):
  2.     temp=a()
  3.     if temp not in zifu:
  4.         zifu.append(string1[t])
  5.         cishu.append(string1.count(temp))
  6.     t += 1
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-9-8 08:10:54 | 显示全部楼层
  1. while t < len(string1):
  2.     if (a1:=a()) not in zifu:
  3.         zifu.append(string1[t])
  4.         cishu.append(string1.count(a1))
  5.     t += 1
复制代码


python3.8+语法
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2020-9-8 09:26:41 | 显示全部楼层    本楼为最佳答案   
错误原因:在第22行和第24行分别执行了 a() ,相当于每次 while 循环,a() 执行了两次,也就是跳过两个字符,所以 while 循环执行到一半的时候,a()就已经达到 string1 的结尾了
帮你把 while 这里修改了,下面这种写法是3.8以前的版本写法。3.8版本之后出现了 海象赋值(:=),也就是2楼所写的那样,就可以少写一行了。

  1. while t < len(string1):
  2.     temp=a()
  3.     if temp not in zifu:
  4.         zifu.append(string1[t])
  5.         cishu.append(string1.count(temp))
  6.     t += 1
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-8 10:11:58 | 显示全部楼层

感谢大神
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-8 10:13:07 | 显示全部楼层
本帖最后由 来包利子 于 2020-9-8 10:23 编辑
sunrise085 发表于 2020-9-8 09:26
错误原因:在第22行和第24行分别执行了 a() ,相当于每次 while 循环,a() 执行了两次,也就是跳过两个字符 ...


感谢大神。

我还想再追问一下。 搜狗截图20年09月08日1020_1.png

变量不是‘贴标签’吗,为什么命名变量会让函数的功能发生变化?命名之前,函数运行一次会初始化一次;命名之后,函数就不会初始化了。
您提的解决办法也是一个例子。为什么直接使用a()会执行读取操作,而用一个变量命名之后就不会执行?

希望大神能指点指点
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-8 11:03:55 | 显示全部楼层
来包利子 发表于 2020-9-8 10:13
感谢大神。

我还想再追问一下。

每执行一次yihao()就会返回一个function object 相当于初始化
而yihao()() 初始化是在第一个括号 和命名没关系 命名是为了后面可以引用
每个function object都有自己的__closure__属性(了解一下就行)
  1. a = yihao()
  2. b = yihao()
  3. a()
  4. a()
  5. a()
  6. print([str(c.cell_contents) for c in a.__closure__][0]) # 3
  7. b()
  8. b()
  9. print([str(c.cell_contents) for c in b.__closure__][0]) # 2
复制代码

用变量去引用yihao()返回的function object是必要的
闭包和递归都是内存杀手
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-9-8 18:21:15 | 显示全部楼层
kogawananari 发表于 2020-9-8 11:03
每执行一次yihao()就会返回一个function object 相当于初始化
而yihao()() 初始化是在第一个括号 和命名 ...

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-4 01:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表