【有书共读01】《python学习手册》读书笔记十四

第十九章:函数的高级话题

当开始使用函数时,就开始面对如何将组件聚合在一起的选择了。例如,如何将任务分解成为更有针对性的函数(导致了聚合性)、函数将如何通信(耦合性)等。

原书内容:

几点原则:

1.耦合性:对于输入使用参数并且对于输出使用return语句
只有在真正必要的情况下使用全局变量。全局变量通常是一种蹩脚的函数间进行通信的办法。它们引发了依赖关系和计时的问题,会导致程序调试和修改的困难
2.耦合性:不要改变可变类型的参数,除非调用者希望这样做。
3.聚合性:每一个函数都应该有一个单一的、统一的目标。在设计完美的情况下,每一个函数都应该做一件事:这件事可以用一个简单说明句来总结。如果这个句子很宽泛(例如,“这个函数实现了整个程序”),或者包含了很多的排比(例如,“这个函数让员工产生并提交了一个比萨订单”),你也许就应该想想是不是要将它分解成多个更简单的函数了。
4.大小:每一个函数应该相对较小。

5.耦合:避免直接改变在另一个模块文件中的变量
============================================================================

递归函数

递归函数即直接或间接地调用自身已进行循环的函数。

--------------------------------------------------------------------------------------------------------------------------

用递归求和

对一个数字列表求和,可以使用内置的sum函数,或者自己编写一个更加定制化的版本:
  1. >>> def mysum(L):
  2. if not L:
  3. return 0
  4. else:
  5. return L[0] + mysum(L[1:])
  6. >>> mysum([1,2,3,4])
  7. 10
在每一层中,这个函数都递归地调用自己来计算列表剩余的值的和,这个和随后加到前面的一项中。
当列表变为空的时候,递归循环结束并返回0。
--------------------------------------------------------------------------------------------------------------------------

编码替代方案

有趣的是,我们也可以使用Python的三元if/else表达式在这里保存某些代码资产。也可以使用Python3.0的扩展序列赋值来使得第一个/其他的解包更简单
---------------------

>>> def mysum1(L):
return 0 if not L else L[0] +mysum1(L[1:])

>>> def mysum2(L):
return L[0] if len(L)==1 else L[0]+mysum2(L[1:])

>>> def mysum3(L):
first,*rest = L
return first if not rest else first+ mysum3(rest)

>>> L = [1,2,3,4]
>>> mysum1(L),mysum2(L),mysum3(L)
(10, 10, 10)
---------------------
上述三个例子中的后面两个会由于空的列表而失败,这是需要注意的地方。
但考虑到支持+的任何对象类型的序列,而不只是数字,后面两种方法更有通用性。

>>> mysum1(['a','b','c','d'])
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
mysum1(['a','b','c','d'])
File "<pyshell#30>", line 2, in mysum1
return 0 if not L else L[0] +mysum1(L[1:])
File "<pyshell#30>", line 2, in mysum1
return 0 if not L else L[0] +mysum1(L[1:])
File "<pyshell#30>", line 2, in mysum1
return 0 if not L else L[0] +mysum1(L[1:])
File "<pyshell#30>", line 2, in mysum1
return 0 if not L else L[0] +mysum1(L[1:])
TypeError: Can't convert 'int' object to str implicitly
>>> mysum2(['a','b','c','d'])
'abcd'
>>> mysum3(['a','b','c','d'])
'abcd'
--------------------- --------------------------------------------------------------------------------------------------------------------------
循环语句VS递归
尽管递归对于上述的求和的例子有效,但在这种环境中,它可能过于追求技巧了。实际上,递归在Python中并不是很常用,因为Python更强调像循环这样的简单的过程式语句,循环语句通过更为自然。例如,while循环常常使得事情更为具体一下:
---------------------

  1. >>> L = [1,2,3,4,5]
  2. >>> mysum = 0
  3. >>> while L:
  4. mysum+=L[0]
  5. L = L[1:]
  6. >>> mysum
  7. 15


更好的情况是,for循环为我们自动迭代,使得递归在大多数情况下不必使用(并且,很可能,递归在内存空间和执行时间方面效率较低)
>>> L = [1,2,3,4,5]
>>> mysum = 0
>>> for x in L:
mysum+=x


>>> mysum
15
--------------------------------------------------------------------------------------------------------------------------
处理任意结构
另一方面,递归可以要求遍历任意形状的结构。作为递归在这种环境中的应用的一个简单例子,考虑像下面这样的一个任务:计算一个嵌套的子列表结构中所有数字的总和:
[1,[2,[3,4],5],6,[7,8]]

简答的循环在这里不起作用,因为这不是一个线性迭代。嵌套的循环语句也不够用,因为子列表可能嵌套到任意的深度并且以任意的形式嵌套。相反,可以使用递归来对应这种一般性嵌套,以便顺序访问子列表:

>>> def sumtree(L):
tot=0
for x in L:
if not isinstance(x,list):
tot += x
else:
tot += sumtree(x)
return tot

>>> L=[1,[2,[3,4],5],6,[7,8]]
>>> sumtree(L)
36
>>> sumtree([1,[2,[3,[4,[5,[6,[7,[8]]]]]]]])
36
>>> sumtree([[[[[[[[1],2],3],4],5],6],7],8])
36
留意这段脚本末尾的测试案例。尽管这个例子是人为编写的,它是更大的程序的代表,例如,继承树和模块导入链可以战术类似的通用结构。
---------------------

待续..#笔记##读书笔记#
全部评论

相关推荐

07-25 13:46
门头沟学院 Java
点赞 评论 收藏
分享
06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
夕颜不需要停机维护:xd能把idea都写上去那说明是真没得写了
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
昨天 17:23
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务