1、函数和过程的定义:

1) 函数定义:函数是逻辑结构化和过程化的一种编程方法。

2) 过程定义:过程就是简单特殊没有返回值的函数。

当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,所以在python中即便是过程也可以算作函数。

3)编写函数的注意事项:
a. 尽量不要使用全局变量。
b. 如果参数是可变类型数据,在函数内,不要修改它。
c. 每个函数的功能和目标要单纯,不要试图一个函数做很多事情。
d. 函数的代码行数尽量少。
e. 函数的独立性越强越好,不要跟其它的外部东西产生关联。

  1. python中函数定义方法:
  2.  
  3. def test(x):
  4. "The function definitions" #函数体
  5. x+=1 #函数体
  6. return x #函数体:写在缩进块中
  7.  
  8. def:定义函数的关键字
  9. test:函数名,需要符合标识符规则
  10. ():内可定义形参
    “:”:不可省略,
  11. "":文档描述(非必要)一般在每个函数名字的下面,还要比较多的说明,这个被称为“文档”,在文档中主要是说明这个函数的用途。(三引号的文档内容)
  12. x+=1:泛指代码块或程序处理逻辑
  13. return:定义返回值
  14.  
  15. 调用运行:可以带参数也可以不带--函数名()

2. 函数的意义:

1)代码重用

2)保持一致性,易维护

3)可扩展性

3. 函数返回值

返回值数=0:返回None

返回值数=1:返回object

返回值数>1:返回tuple,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值。

函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。类似break作用:return可以结束正在执行的函数。将变量result的值返回,把返回值赋值给变量。如果没有赋值语句,函数照样返回值,但是它飘忽在内存中,我们无法得到,并且最终还被当做垃圾被python回收了。

4.传值方式和参数

1) 传值方式

● 传统方式----函数调用时传参,直接给参数

● 调用函数传值----通过变量间接给参数。要传的值放到元组(或字典)中,赋值给一个变量bars,然后在函数调用时传参add(*bars)的方式,把值传到函数内。有点像收集参数的逆过程。注意的是,元组中元素的个数,要跟函数所要求的变量个数一致。

使用一个星号*,是以元组形式传值,如果用**的方式,是以字典的形式传值。

2) 参数

本质上就是一个“占位符”,当调用一个函数的时候,并不是赋值了一份参数的值来替换占位符,而是把占位符指向了变量,进而指向了对象。换个角度说,就是通过一连串的接力动作,把对象传给了函数。这样说来,你就可以在函数内部改变那个对象了。

a. 形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

b. 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

c. 位置参数是标准调用,按照顺序以此对参数进行赋值,实参与形参必须数量一致,位置一一对应。def foo(p1,p2,p3,...)

d. 关键字参数:位置无需固定,位置参数和关键字参数混用的时候,位置参数一定要在关键字参数的左边。

e. 默认参数:def foo(p1=value1,p2=value2,...)由于函数的参数按从左到右的顺序匹配,所以默认参数只能定义在必需参数的后面。作用是简化调用,只需要把必须的参数传进去。但在需要的时候,又可以传入额外的参数来覆盖默认参数值。

f. 参数组可变参数:适用于不确定参数个数的时候,def foo(*args) 和def foo(**kargs)

Python解释器会把传入的一组参数组装成一个tuple传递给可变参数,因此,在函数内部,直接把变量 args 看成一个 tuple 就好了。

参数个数的不确定性:输入的参数个数不确定

● 其它参数全部通过*arg,以元组的形式由arg收集起来。即使只有一个值,也是用tuple收集它。特别注意,在tuple中,如果只有一个元素,后面要有一个逗号。还有一种可能,就是不给那个*args传值,也是许可的,这时候*args收集到的是一个空的tuple。

● 如果用**kargs的形式收集值,会得到dict类型的数据,但是,需要在传值的时候说明“键”和“值”,因为在字典中是以键值对形式出现的。

5. 变量

1)其本质也是占位符。变量名命名得符合标识符规则,必须是大小写英文、数字和下划线(_)的组合,且不能用数字开头。通常使小写字母来命名python中的变量,也可以在其中加上下划线什么的,表示区别。

全局变量:在程序的一开始定义的变量,作用域是整个程序

局部变量:在子程序中定义的变量,作用域是定义该变量的子程序。

当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。如果在局部要对全局变量修改,需要在局部也要先声明该全局变量:使用global 变量名。

2)读取变量顺序:如果无global关键字,先局部再全局,对于不可变数据类型的变量无法对全局变量重新赋值,对于可变数据类型的变量,可以对内部元素进行操作;如果有global关键字,先局部,再局部的全局变量,最后再全局,变量的本质就是全局的那个变量,可读取可赋值。

3) global关键字用来在函数或其他局部作用域中使用全局变量。但是如果不修改全局变量也可以不使用global关键字。

nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量。

6. 前向引用

python是解释性语音,函数的定义必须在调用前面。

7.递归函数

递归特性:

a. 必须有一个明确的结束条件

b. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

c. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html

尾递归优化:http://egon09.blog.51cto.com/9161406/1842475

8. Lambda匿名函数:使代码简洁

lambda arg1, arg2, ...argN : expression using arguments

●  在lambda后面直接跟变量

●  变量后面是冒号

●  冒号后面是表达式,表达式计算结果就是本函数的返回值

9. 函数式编程:map(), reduce(), filter()

满足俩个特性任意一个即为高阶函数

1) 函数的传入参数是一个函数名

2) 函数的返回值是一个函数名

map(func,seq)

  1. array=[1,3,4,71,2]
  2.  
  3. ret=[]
  4. for i in array:
  5. ret.append(i**2)
  6. print(ret)
  7.  
  8. #如果我们有一万个列表,那么你只能把上面的逻辑定义成函数
  9. def map_test(array):
  10. ret=[]
  11. for i in array:
  12. ret.append(i**2)
  13. return ret
  14.  
  15. print(map_test(array))
  16.  
  17. #如果我们的需求变了,不是把列表中每个元素都平方,还有加1,减一,那么可以这样
  18. def add_num(x):
  19. return x+1
  20. def map_test(func,array):
  21. ret=[]
  22. for i in array:
  23. ret.append(func(i))
  24. return ret
  25.  
  26. print(map_test(add_num,array))
  27. #可以使用匿名函数
  28. print(map_test(lambda x:x-1,array))
  29.  
  30. #上面就是map函数的功能,map得到的结果是可迭代对象
  31. print(map(lambda x:x-1,range(5)))

map()

filter(func,seq)

  1. #电影院聚集了一群看电影bb的傻逼,让我们找出他们
  2. movie_people=['alex','wupeiqi','yuanhao','sb_alex','sb_wupeiqi','sb_yuanhao']
  3.  
  4. def tell_sb(x):
  5. return x.startswith('sb')
  6.  
  7. def filter_test(func,array):
  8. ret=[]
  9. for i in array:
  10. if func(i):
  11. ret.append(i)
  12. return ret
  13.  
  14. print(filter_test(tell_sb,movie_people))
  15.  
  16. #函数filter,返回可迭代对象
  17. print(filter(lambda x:x.startswith('sb'),movie_people))

filter()

reduce(func, iterable[, initializer])

  1. from functools import reduce
  2. #合并,得一个合并的结果
  3. array_test=[1,2,3,4,5,6,7]
  4. array=range(100)
  5.  
  6. #报错啊,res没有指定初始值
  7. def reduce_test(func,array):
  8. l=list(array)
  9. for i in l:
  10. res=func(res,i)
  11. return res
  12.  
  13. # print(reduce_test(lambda x,y:x+y,array))
  14.  
  15. #可以从列表左边弹出第一个值
  16. def reduce_test(func,array):
  17. l=list(array)
  18. res=l.pop(0)
  19. for i in l:
  20. res=func(res,i)
  21. return res
  22.  
  23. print(reduce_test(lambda x,y:x+y,array))
  24.  
  25. #我们应该支持用户自己传入初始值
  26. def reduce_test(func,array,init=None):
  27. l=list(array)
  28. if init is None:
  29. res=l.pop(0)
  30. else:
  31. res=init
  32. for i in l:
  33. res=func(res,i)
  34. return res
  35.  
  36. print(reduce_test(lambda x,y:x+y,array))
  37. print(reduce_test(lambda x,y:x+y,array,50))

reduce()

区别:

map()是依次处理,对列表每个元素进行处理,结果是处理后的列表,顺序一样。

filter()是遍历元素,进行筛选处理,布尔值为True的的留下来,得出一个筛选后的结果。

reduce()是压缩处理,最后得出一个值。

  1. #map,filter,reduce,可以处理所有数据类型
  2.  
  3. name_dic=[
  4. {'name':'alex','age':1000},
  5. {'name':'wupeiqi','age':10000},
  6. {'name':'yuanhao','age':9000},
  7. {'name':'linhaifeng','age':18},
  8. ]
  9. #利用filter过滤掉千年王八,万年龟,还有一个九千岁
  10. def func(x):
  11. age_list=[1000,10000,9000]
  12. return x['age'] not in age_list
  13.  
  14. res=filter(func,name_dic)
  15. for i in res:
  16. print(i)
  17.  
  18. res=filter(lambda x:x['age'] == 18,name_dic)
  19. for i in res:
  20. print(i)
  21.  
  22. #reduce用来计算1到100的和
  23. from functools import reduce
  24. print(reduce(lambda x,y:x+y,range(100),100))
  25. print(reduce(lambda x,y:x+y,range(1,101)))
  26.  
  27. #用map来处理字符串列表啊,把列表中所有人都变成sb,比方alex_sb
  28. name=['alex','wupeiqi','yuanhao']
  29.  
  30. res=map(lambda x:x+'_sb',name)
  31. for i in res:
  32. print(i)

map,filter,reduce

10、内置函数

  1. all() # 判断序列的所有元素是否布尔值,返回布尔值。e.g. print(all([1,2,""])) -- False
  2. any() # 当序列中有某个元素的布尔值为True,返回True。 e.g. print(all([1,2,""])) -- True
  3. adb() # 获取绝对值。 e.g. print(abs(-1))
  4. sum() # 加法。 e.g. print(sum([0,4], 2)) -- 6
  5. divmod() # 取商得余数。 e.g. print(divmod(10,3)) --(3, 1)
  6. pow(xyz) #求次方。两个参数:x**y;三个参数:x**y%z. e.g. print(pow(3,3,2)) -- 1
  7. round() # 四舍五入 e.g. print(round(4.5)) -- 4
  8. bin() # 十进制转换成二进制。e.g. print(bin(3)) -- 0b11
  9. hex() # 十进制转换成十六进制。e.g. print(bin(12)) -- 0xc
  10. oct() # 十进制转换成八进制。e.g. print(oct(9)) -- 0o11
  11. float() # 将一个数值或者字符转换成浮点型数值,不提供参数的时候,返回0.0。 e.g. print(float(3)) -- 3.0
  12. int() # 将一个数字或base类型的字符串转换成整数。
  13. dict() # 转换成字典
  14. list() # 转换成列表
  15. tuple() # 转换成元组
  16. set() # 创建一个可变集合。 print(set("qiwsir")) -- {'r', 's', 'q', 'w', 'i'}
  17. frozenset() #创建一个不可变集合。 e.g. print(frozenset("qiwsir")) -- frozenset({'w', 'i', 's', 'q', 'r'})
  18. str() # 转换成字符串
  19. format() # 格式化字符串
  20. eval() # 提取字符串的数据结构或者运行字符串的表达式。e.g. dic_str="{'name':'alex'}" d1=eval(dic_str) print(d1['name']) -- alex ; express="3+(4/2-1)*7" print(eval(express)) -- 10.0
  21. bytes() # 将字符(串)转换成对应的字节码, e.g. print(bytes("陈",encoding="utf-8")) print(bytes("陈",encoding="utf-8").decode("utf-8"))编码解码要一致
  22. len() # 返回对象(字符、列表、元组等)长度或项目个数。
  23. enumerate() #对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),利用enumerate可以同时获得索引和值。一般跟for一起使用。list1 = ["22", "33"] for index, item in enumerate(list1): print(index,item) -- 0 22 , 1 33
  24. map() # 依次处理列表每个元素,结果是处理后的列表,顺序一致。
  25. filter() # 遍历元素,进行筛选处理,布尔值为True的的留下来,得出一个筛选后的结果
  26. slice() # 切片。 e.g. l='qiwsir' print(l[slice(1,4,2)]) -- is
  27. reversed() # print(list(reversed([1,2,3])))
  28. sorted() # 同类型比较大小并排序。 e.g. l=[3,6,-1,0] print(sorted(l)) -- [-1,0,3,6] l=['c','a'] print(sorted(l)) -- ['a', 'c']
  29. max() # 返回序列的最大值 e.g. L=[1,334,-2] print(max(L)) -- 334
  30. min() # 返回序列的最小值 e.g. print(min(L)) -- -2
  31. zip() # 从参数中的多个迭代器取元素组合成一个新的迭代器,又称拉链函数 e.g.print(list(zip(('a','b','c','d'),(1,2,3)))) -- [('a', 1), ('b', 2), ('c', 3)]
  32. range() # 创建一个整数列表,一般用在 for 循环中。e.g. for i in range(0, 20, 5): print(i) -- 0 5 10 15
  33. chr() # 转换出ASCII表的对应字符。 e.g.print(chr(97)) -- a。
  34. ord() # 转换出ASCII表的对应的编码。 e.g. print(ord('a')) -- 97
  35. hash() # 返回hash值。可哈希的数据类型可变,不可hash的数据类型不可变。一般用于数字校验。
  36. isinstance(a,b) #判断a是否是b的实例。e.g. print(isinstance('as',str)) --True
  37. type() # 返回对象的类型
  38. id() #用于获取对象的内存地址。e.g. print(id(1)) -- 1498639840; print(id('1')) -- 8088912
  39. dir() # 打印出某个对象的方法。
  40. help() # 打印方法的详细使用方式。e.g. print(help(all))
  41. globals() # 返回全局变量的字典(包括系统提供的),修改其中的内容,值会真正的发生改变。
  42. locals() # 返回是当前局部变量的字典,修改locals() 中变量值的时候,实际上对于原变量本身是没有任何影响的。
  43. next()
  44. object()
  45. open()
  46. print()
  47. property()
  48. repr() #将对象转化为供解释器读取的形式。
  49. vars()
  50. delattr()
  51. hasattr()
  52. getattr()
  1. 字典的运算:最小值,最大值,排序
  2. salaries={
  3. 'egon':3000,
  4. 'alex':100000000,
  5. 'wupeiqi':10000,
  6. 'yuanhao':2000
  7. }
  8.  
  9. 迭代字典,取得是key,因而比较的是key的最大和最小值
  10. >>> max(salaries)
  11. 'yuanhao'
  12. >>> min(salaries)
  13. 'alex'
  14.  
  15. 可以取values,来比较
  16. >>> max(salaries.values())
  17. 100000000
  18. >>> min(salaries.values())
  19. 2000
  20. 但通常我们都是想取出,工资最高的那个人名,即比较的是salaries的值,得到的是键
  21. >>> max(salaries,key=lambda k:salary[k])
  22. 'alex'
  23. >>> min(salaries,key=lambda k:salary[k])
  24. 'yuanhao'
  25.  
  26. 也可以通过zip的方式实现
  27. salaries_and_names=zip(salaries.values(),salaries.keys())
  28.  
  29. 先比较值,值相同则比较键
  30. >>> max(salaries_and_names)
  31. (100000000, 'alex')
  32.  
  33. salaries_and_names是迭代器,因而只能访问一次
  34. >>> min(salaries_and_names)
  35. Traceback (most recent call last):
  36. File "<stdin>", line 1, in <module>
  37. ValueError: min() arg is an empty sequence
  38.  
  39. sorted(iterablekey=None,reverse=False)

【参考文献】

http://www.cnblogs.com/linhaifeng/articles/6113086.html

http://blog.51cto.com/egon09

第三篇、Python函数的更多相关文章

  1. 【0728 | 预习】第三篇 Python基础

    第三篇 Python基础预习 Part 1 变量 一.什么是变量? 二.为什么要有变量? 三.定义变量 四.变量的组成 五.变量名的命名规范 六.变量名的两种风格 Part 2 常量 Part 3 P ...

  2. Python成长之路【第三篇】函数

    函数 一.背景 在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处 ...

  3. python【第三篇】函数

    内容大纲: 1.函数基本语法与特性 2.参数与局部变量 3.返回值 4.递归 5.匿名函数lambda 6.函数式编程介绍 7.高阶函数 8.内置函数 1.函数基本语法与特性 函数的定义:函数是指将一 ...

  4. python 【第三篇】函数基础

    深浅拷贝 set是一个无序且不重复的元素集合访问速度快天生解决重复问题 #!/usr/bin/env python3 # -*- coding:utf-8 -*- #深浅拷贝 import copy ...

  5. 【Python之路】第三篇--Python基本数据类型

    运算符 1.算数运算: # 在py2的 取整除运算中 9//2 = 4.0 # 引入 from __future__ import division 9//2 = 4.5 # py3中不需要! 2.比 ...

  6. 深入理解this机制系列第三篇——箭头函数

    × 目录 [1]痛点 [2]解决 [3]基本用法[4]回调函数[5]注意事项 前面的话 this机制与函数调用有关,而作用域则与函数定义有关.有没有什么是可以将this机制和作用域联系起来的呢?本文将 ...

  7. 第三篇 Python关于mysql的API--pymysql模块, mysql事务

    python关于mysql的API--pymysql模块 pymysql是Python中操作MySQL的模块,其使用方法和py2的MySQLdb几乎相同. 模块安装 pip install pymys ...

  8. 第十七篇 Python函数之闭包与装饰器

    一. 装饰器 装饰器:可以拆解来看,器本质就是函数,装饰就是修饰的意思,所以装饰器的功能就是为其他函数添加附加功能. 装饰器的两个原则: 1. 不修改被修饰函数的源代码 2. 不修改被修饰函数的调用方 ...

  9. 第十二篇 Python函数之全局变量&局部变量&递归函数

    全局变量:在定义的时候,顶头写的,没有任何缩进的变量就是全局变量. 全局变量的特点:在当前文件里的任何地方都可以进行调用 局部变量:在子程序里定义的变量,就是局部变量. 子程序:比如.py文件里,写的 ...

  10. 第十一篇 Python函数之定义&形参&实参&位置参数&关键字参数&可变长参数&默认参数

    函数的定义:函数是为了完成某一特定功能的,函数是逻辑结构化和过程化的一种编程方法 函数的定义格式,函数一般都是有返回值的 #语法 #函数名要能反映其意义 def 函数名(参数1,参数2,参数3,... ...

随机推荐

  1. 使用Java API方式的MapReduce练习

    众所周知,hadoop生态圈的多数组件都是使用java开发的. 那么使用Java API方式实现起来,显得要比其它语言效率更高,更原生态. 前面有一个Hadoop学习笔记02_MapReduce练习 ...

  2. swap 用指针交换两个整型数值

  3. 使用Jackson解析首字母大写的json字符串

    Jackson在解析返回的json字符串时始终报错,纠结很久之后才找到原因,原来是是由于json字符串中的字母都是首字母大写,导致jackson找不到相应的KEY. 在项目中经常使用从服务器获取的数据 ...

  4. php批量检测和去掉bom头(转)

    <?php //有些php文件由于不小心保存成了含bom头的格式而导致出现一系列的问题.以下是批量清除bom头的代码 if (isset ( $_GET ['dir'] )) { //confi ...

  5. kettle在本地执行向远程hdfs执行转换错误"Couldn't open file hdfs"

    kettle在本地执行向远程hdfs执行转换时,会出现以下错误: ToHDFS.0 - ERROR (version 7.1.0.0-12, build 1 from 2017-05-16 17.18 ...

  6. 【Java】字节数组转换工具类

    import org.apache.commons.lang.ArrayUtils; import java.nio.charset.Charset; /** * 字节数组转换工具类 */ publi ...

  7. python 4

    一.列表相关操作 l = ['布偶猫', '小断腿', '大白'] # . append l.append('哎呀') print(l) # . insert l.insert(, '小猪佩琪') p ...

  8. day05 判断敏感字符

    1.判断一个字符是不是敏感字符: in 1.str v ="年龄多大了" if "大" in v: print("敏感") 2.list/t ...

  9. django 增加自定义权限的一个博客,讲的很详细

    来自  https://www.cnblogs.com/huangxm/p/5770735.html

  10. Linux双线双网卡双IP双网关设置方法

    机房上架了一台测试机,系统是Ubuntu 9.04 X64的系统,母机IBM X336机器.用户需求是双线,故采用一个网卡配置电信地址,另一个网卡配置联通地址,安装好系统后配置好IP发现联通地址和电信 ...