004-Python函数

目录

  1. 引入函数话题
  2. 自定义函数
  3. 高级内置函数map的用法
  4. 高级内置函数filter的用法
  5. 高级内置函数reduce的用法
  6. 思考总结           


  1. 引入函数话题

        原先写过一篇001-python字符串,里面有提到,如何在编译器里看Python内置函数的源码,比如说你用的是Pycharm,那么你只需要Ctrl+鼠标左键关键词就能进入源码;如果你用的是Spyder,那么你只需要在Console中输入help(关键词)然后回车就能进入源码。我用的是Spyder,所以我在Console输入help(list)+回车,就进入到list内置函数的源码中了,下面会列出list的所有内置函数。


    

        那么像str、list、tuple、dict、set这五个基本数据类型,内置函数加起来加起来数量没有一百个也有九十个,这么多的函数短时间内肯定是记不住的。就算记住了,也没什么用,因为,我不花费时间去背这些函数,而是把时间花到敲代码上,就像打篮球一样,光看NBA是不行的,必须亲身到球场上,去挥洒汗水,大量的打铁,大量的失误,才能造就一个神射手。就像学吉他一样,只跟着教程学习是不行的,必须亲手握住一把琴,拨弄琴弦,大量的噪音,大量的重复,才能弹奏出行云流水的感觉。好像是莫扎特说过:“我每天练习八个小时,你仅用‘天才’两个字就掩盖了我的所有努力。”这话听起来是不是很带劲?你我一样,都是很普通的人,要想得到自己想要的东西,光靠努力是没用的,需要拼命。

        好了,鸡汤就到此为止,接下来进入正题。

2.自定义函数

        本来想从为什么需要函数写起,后来想了想,没必要。

        直接说自定义函数吧,首先就是保留字也叫关键词 def,这里的关键词等价于保留字,和我上面说的“Ctrl+鼠标单击关键词”里面的“关键词”不是一个意思啊。(活生生给自己刨个坑,填一下)

        Python中两行代码就可以查看保留字:

import keyword

print(keyword.kwlist)

        运行结果:


        如果我没数错的话,应该是33个,哎呀,我为啥要一个一个数?一个len()函数不就出来长度了吗?代码如下:

import keyword
print(keyword.kwlist)
print(len(keyword.kwlist))

        运行结果:


        再次验证我数的没错!大家要记住学以致用呀。

        因为Python是弱类型语言,所以只需要保留字def+函数名+括号(形参)+冒号就行了,不用声明返回类型。当然函数也没用什么神奇的,就是把代码封装起来了。比如,我把print()封装一下,起个名字叫 打印:

def 打印(obj):
    print(obj)
打印(123)
打印('Hello World!')

        这就是一个自定义函数,是不是瞬间函数的神秘面纱就没有了。

3.高级内置函数map的用法

        我有一个需求:实现列表 mList = [1, 3, 7, 16, 8, 20] 中的每个元素能够自增1,自减1

        用自定义函数的写法就是这样:

mList = [1,3,7,16,8,20]
def add_one(x):
    return x+1
def reduce_one(x):
    return x-1
def map_test(func,iterable):
    result = []
    for i in iterable:
        res = func(i)
        result.append(res)
    return result
print(map_test(add_one,mList))
print(map_test(reduce_one,mList))

        运行结果:

        

        这里写的主要的函数 map_test(func,iterable),传入的第一个参数是一个函数,第二个参数是一个可迭代对象。在map_test内部,对可迭代对象循环遍历取每一个元素,然后把取出来的元素 i 传给我们自己选择的函数 func(),然后将返回结果赋值给一个变量res,再将每个结果append进一个新的列表result。

        其实Python早就觉得这个功能很重要,于是就替我们写好了这个map_test函数,人家起名叫map(),同样也是传两个参数,第一个是函数,第二个是可迭代对象,然后返回的是一个map对象,我们需要转化为可迭代对象并打印,代码如下:

#内置函数 map
mList = [1,3,7,16,8,20]
result = map(lambda x:x+1,mList)
print(result)
print(list(result))

        运行结果:


        map()函数的作用就是遍历每个元素进行处理,返回一个和传入等长的可迭代对象。

        所谓的内置函数,就是把一些类似下面代码的逻辑给封装好了,只暴露给你参数接口,你只需要调用传参就能使用。

 result = []
    for i in iterable:
        res = func(i)
        result.append(res)
    return result

4.高级内置函数filter的用法

        把内置函数map()的来龙去脉说清楚之后,filter()就很好说了,顾名思义,filter  过滤器,使用道理相同,我们只需要传参就行了,同样还是第一个参数传一个函数,第二个参数传一个可迭代对象,示例代码如下:

#内置函数filter
mList = [1,3,7,16,8,20]
result = filter(lambda x:x>7,mList)
print(result)
print(list(result))

        运行结果:


        filter()函数的作用就是按照要求进行过滤,把符合要求的元素返回,返回的可迭代对象长度<=传入的可迭代对象长度。

5.高级内置函数reduce的用法

        map()、reduce()都说了,这个reduce就直接上例子了:

# reduce()函数,需要import
from functools import reduce

num_list = [0,1,2,3,4,5,6,7,8,9,]
print(reduce(lambda x,y:x+y,num_list))

        运行结果:


        这里,reduce()的和map()、filter()使用上不同之处有两点:一、需要import一下,二、直接返回一个值,不用再强制转化为可迭代对象。很奇怪,reduce()同样是内置函数,待遇咋就和其他的不一样呢?非得import一下。甚是奇怪。

        reduce()函数的作用就是将每个元素和它的相邻元素进行运算,将传入的可迭代对象压缩成一个值返回,

6.总结    

        大数据方面有知识叫MapReduce,我们现在已经知道,map()用于数据处理,reduce()用于数据压缩,所以MapReduce大概就是处理并压缩数据的意思(我猜测的,不靠谱)。

        map()、filter()、reduce()三者的返回长度递减。之所以说这三个是高级内置函数,我觉得是因为他们本身是函数,而传的参数又有函数,比较难理解。

        在这方面廖大神也有写到:廖雪峰的官方网站

        文章到这本应该要结束了,但是我前两天考试考了Python,遇到三个题(我做错了):

1.    print(chr(ord("D")))  的结果是什么?

        这道题考察的是一对作用相反的函数,而我恰巧有没使用过ord(),所以做错了。

        我给出的错误答案是:68

        正确答案是: D

        解析:因为ord()的作用是转化为ASCII码,也就是说 D 对应的 ASCII 码为 68,但是外围括号还有一个 chr(),而chr()的作用就是把ASCII码转为字符,所以经过这一对作用相反的函数操作,D原封不动,打印结果还是D。

 2.  Python中没有以下哪种类型?()

        A.int           B.float         C.chr         D.str

        我给出的错误答案是:B 

        正确答案是:C

        解析:因为我当时脑子里想的是Python中浮点数只有double,没有float,结果是记反了,正解是python中只有float,没有double。至于为什么python中没有专门的char类型,通过引用一篇知乎文章来解释:https://www.zhihu.com/question/37055272

3.输入一段英文,将其中  单独的 小写i   转化为 大写I.

        这道题我是亲手练习过的,而且是在CSDN发表过的,结果还是没做对。原因就是我当时做的和发表的都是错的。错的原因是我看了一篇错误的文章,而我当时初学,又没有分辨能力,在此贴出这篇坑*的文章:坑*的文章

        坑的地方不在原作者,在于下面那个装x的评论,还给出两种解决方案,于是我就省懒劲照着评论的第一个方案,也就是不用正则表达式的那个方案。

        我给出的错误答案是:

s = input()
s = s.replace('i','I')
print(s)

        正确答案的一种方案是:

import re
x = "i ii i i."
pattern = re.compile(r'(?:[^\w]|\b)i(?:[^\w])')
while True:
    result = pattern.search(x)
    if result:
        if result.start(0) != 0:
            x = x[:result.start(0)+1]+'I'+x[result.end(0)-1:]
        else:
            x = x[:result.start(0)]+'I'+x[result.end(0)-1:]
    else:
        break
print(x)

        运行结果:

        

        解析:这段代码用到了正则表达式,我目前看不懂,结果运行是正确了,但是有一个bug,就是最后必须要有一个点或者逗号或者空格做结尾,否则最后那个小写的i 依然无法替换成大写的I。也许这就是人家题的原先意思吧,即:输入一段英文,这段英文是有意义的,也就是说是符合文章标准,有标点符号的,只不过,不小心把大写的I 写成了小写的i。

        但是不管怎么说,他这个代码依然不完美。这里挖个坑吧,我改天再来填好,就是写一个能解决上面提到那个bug的程序。

        终于该结尾了,这里贴出来Python3的全部build-in function:


        这里分享两个资源:

Python3内置函数中文源码:http://www.runoob.com/python/python-built-in-functions.html

Python3所有源码(英文):http://tool.oschina.net/apidocs/apidoc?api=Python%2Freference


-----------------------------------------华丽丽的结尾线-----------------------------------------












猜你喜欢

转载自blog.csdn.net/midnight_time/article/details/80960342
004