51假期读书笔记(上)——流畅的python

今天是51假期,我开启了新的一章,✌️!

第五章 一等函数

编程语言理论家将“一等对象”定义为满足下述条件的程序实体:

  • 在运行时创建
  • 能赋值给变量或者数据结构中的元素
  • 能作为参数传给函数
  • 能作为函数的返回结果

因此,按照以上的标准,整数、字符串和字典都是一等对象。

5.1 5.1 5.1 把函数视作对象

>>> def func1(n):
...     ''' return n!'''
...     n = n+1
...     return n
... 
>>> func1(1)
2
>>> func1.__doc__
' return n!'
>>> type(func1)
# <class 'function'>

从以上实例中,我得知函数是一个function类型的对象,并且我可以用__doc__获取它的文档属性。

__doc__用于生成对象的帮助文本。

因此,该函数就符合一等对象的全部特征。
可以赋值给变量,也可以作为参数传给函数。

>>> my_func = func1
>>> my_func
<function func1 at 0x103c67b70>
>>> func1
<function func1 at 0x103c67b70>
>>> func1(func1(1))
3

有了一等函数,就可以使用函数式风格来编程。

5.2 5.2 5.2 高阶函数

接受函数作为参数,或者将函数作为结果返回的函数是高阶函数。
我们在第二章提到的sorted()排序的函数也是高阶函数,因为它会将key作为参数会应用到各个元素中进行排序。

如下所示:

>>> fruits = ['strawberry','apple','watermalon','lemon']
>>> sorted(fruits, key=len)
['apple', 'lemon', 'strawberry', 'watermalon']

任何单个参数的函数都可以作为key参数的值。

>>> def reverse(word):
...     return word[::-1]
... 
>>> reverse('my world')
'dlrow ym'
>>> sorted(fruits, key=reverse)
['apple', 'watermalon', 'lemon', 'strawberry']

我们平常比较常用的高阶函数有filter,map,reduce等。其中map和filter还是内置函数,但是由于引入了列表推导和生成式,他们变得不是特别重要了。

下面比较了两种方式:

>>> list(map(func1, range(6)))
[1, 2, 3, 4, 5, 6]
>>> [func1(n) for n in range(6)]
[1, 2, 3, 4, 5, 6]
>>> list(map(func1, filter(lambda n:n%2, range(6))))
[2, 4, 6]
>>> [func1(n) for n in range(6) if n % 2]
[2, 4, 6]

map和filter返回的是一个生成器,因此目前经常会被生成器表达式所取代。

在python2中,reduce是一个内置函数,而在python3中,被放到了functools模块中。

>>> from functools import reduce
>>> from operator import add
>>> reduce(add, range(100))
4950
>>> sum(range(100))
4950

sum和reduce的通用思想都是将某个操作连续应用在序列中的元素上,并且累计之间的结果,返回成一个值。

同样的还有all和any函数:

  • all(iterable)
    如果iterable中元素都是真值,就返回True
  • any(iterable)
    只要iterable中有元素是真值,就返回True
>>> all(range(100))
False
>>> any(range(100))
True
>>> all(range(1,2))
True
>>> any(range(1))
False

在逻辑中,真值(truth value),又称逻辑值(logical value),是指示一个陈述在什么程度上是真的。在计算机编程上多称做布林值、布尔值。

5.3 5.3 5.3 匿名函数

lambda关键式在python表达式中创建匿名函数。
然而,python简单的句法限制了lambda函数的定义体中只能使用纯表达式。也就是说,lambda函数的定义体中不能赋值,也不能使用while,try等语句。

刚才我们那个反转单词的例子就可以用lambda作为key

>>> sorted(fruits, key=lambda word:word[::-1])
['apple', 'watermalon', 'lemon', 'strawberry']

在使用lambda时,由于它的一些局限性,因此建议走以下步骤:

  1. 编写注释,说明下lambda表达式的功能作用
  2. 研究一会儿注释,找出一个名称来概括注释
  3. 将lambda表达式转换成def语句,使用那个名称来定义函数
  4. 删除注释

lambda句法只是语法糖:与def一样,lambda表达式会创建函数对象。

语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的术语,指向计算机语言中添加某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常而言,使用语法糖能够增加程序的可读性,从而减少代码出错的机会。 举个例子,在C语言里面我们经常用a[i][j]表示((a+i)+j),a[i][j]这种写法简洁明了,更容易被人理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值