Python-函数

2018-06-18 01:57:59来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

一、函数作用:

  函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

  函数式编程最重要的是增强代码的重用性和可读性

二、函数的定义和使用

  定义:

1 def 函数名(参数):
2     函数体
3     .....
4     返回值

  -注- 

    def:定义函数的关键字

    返回值后可以跟多个值,最终以元组方式输出

    函数的参数:形参、实参

    形参被调用时才会分配内存空间

    return 执行后,后面的不在执行,且只能有一个return

    Python中所谓的过程就是没有返回值的函数

  参数:

# Python中有三种参数:普通参数、默认参数,动态参数(针对形参说)
# 普通参数
# 此外对参数的理解如下:
def test(x,y,z):# 三个都是普通参数
    print(x)
    print(y)
    print(z)
test(1,2,3)# 实参叫位置参数,赋值时 必须一一对应 不能多,也不能少

test(y=1,x=2,z=3) # 关键字参数,不需要一一对应,不能多,也不能少

test(1,2,z=3) # 位置参数必需放在关键字参数左侧,不能多,也不能少
test(1,2,y=3) # 报错,已经对y赋值,在赋值报错


# 默认参数
def handle(x,type='mysql'):
    print(x)
    print(type)
handle('hello') 
handle('hello',type='sqlite')
handle('hello','sqlite')

# 动态参数(也可以叫参数组)
def test(x,*args):
    print(x)
    print(args)

#######      * 与列表有关     ** 与字典有关
#######      *args
def test(x,*args):
    print(x)
    print(args)
test(1)
# 1
# ()
test(1,2,3,4,5)
# 1
# (2, 3, 4, 5)
test(1,{'name':'alex'})
# 1
# ({'name': 'alex'},)
test(1,['x','y','z'])
# 1
# (['x', 'y', 'z'],)
test(1,*['x','y','z'])
# 1
# ('x', 'y', 'z')
test(1,*('x','y','z'))
# 1
# ('x', 'y', 'z')


def test(x,*args):
    print(x)
    print(args)  # 获得元组 通过for遍历传递
    print(args[0])
    print(args[0][0])
# test(1)
# test(1,2,3,4,5)
# test(1,{'1':1})
test(1,['s','a','dd'])
# test(1,*['s','a','dd'])




#######      **args

def test(x,**kwargs):
    print(x)
    print(kwargs)
test(1,y=2,z=3)
test(1,1,2,2,2,2,2,y=2,z=3) # 报错
test(1,y=2,z=3,z=3)#会报错 :一个参数不能传两个值



######## 混合
def test(x,*args,**kwargs):
    print(x)
    print(args,args[-1])
    print(kwargs,kwargs.get('y'))
# test(1,1,2,1,1,11,1,x=1,y=2,z=3) #报错 x
# test(1,1,2,1,1,11,1,y=2,z=3)

test(1,*[1,2,3],**{'y':1})
test(1,*[1,2,3],**{'y':1,'z':2})

  函数变量:

    分为:全局变量、局部变量

 1 # 如果函数的内容无global关键字,
 2 #   - 有声明局部变量
 3         # NAME = ["产品经理","廖波湿"]
 4         # def qupengfei():
 5         #     NAME = "自己"
 6         #     print('我要搞', NAME)
 7         # qupengfei()
 8 #   - 无声明局部变量
 9         # NAME = ["产品经理","廖波湿"]
10         # def qupengfei():
11         #     NAME.append('XXOO')
12         #     print('我要搞', NAME)
13         # qupengfei()
14 
15 # 如果函数的内容有global关键字
16 #   - 有声明局部变量
17         # NAME = ["产品经理","廖波湿"]
18         # def qupengfei():
19         #     global NAME
20         #     NAME = "自己"
21         #     print('我要搞', NAME)
22         # qupengfei()
23         # 错误示例
24         # NAME = ["产品经理","廖波湿"]
25         # def qupengfei():
26         #     NAME = "自己"
27         #     global NAME
28         #     print('我要搞', NAME)
29         # qupengfei()
30 #   - 无声明局部变量
31         # NAME = ["产品经理","廖波湿"]
32         # def qupengfei():
33         #     global NAME
34         #     NAME = ["阿毛"]
35         #     NAME.append('XXOO')
36         #     print('我要搞', NAME)
37         # qupengfei()
38 
39 ######## 全局变量变量名大写
40 ######## 局部变量变量名小写
41 
42 
43 # 优先读取局部变量,能读取全局变量,无法对全局变量重新赋值 NAME=“fff”,
44 #     但是对于可变类型,可以对内部元素进行操作
45 # 如果函数中有global关键字,变量本质上就是全局的那个变量,可读取可赋值 NAME=“fff”
 1 NAME = ["产品经理","廖波湿"]
 2 
 3 def yangjian():
 4     # NAME = "史正文"
 5     global NAME # 已经声明,NAME就是全局的的那个变量
 6     print('我要搞', NAME)
 7     NAME = "小东北"  # 修改 全局的变量
 8     print('我要搞', NAME)
 9 yangjian()
10 
11 
12 
13 
14 #### nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
15 
16 
17 
18 name = "刚娘"
19 
20 def weihou():
21     name = "陈卓"
22     def weiweihou():
23         nonlocal name   # nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
24         name = "冷静"
25 
26     weiweihou()
27     print(name)
28 
29 print(name)
30 weihou()
31 print(name)
32 刚娘
33 冷静
34 刚娘

  前向引用

 1 ## Python 是先编译后运行
 2 def bar():
 3     print('from bar')
 4 def foo():
 5     print('from foo')
 6     bar()
 7 
 8 foo()
 9 
10 
11 
12 def foo():
13     print('from foo')
14     bar()
15 
16 def bar():
17     print('from bar')
18 foo()
19 
20 
21 
22 报错:不能先调用,后定义 
23 def foo():
24     print('from foo')
25     bar()
26 
27 foo()
28 
29 def bar():
30     print('from bar')

  递归:

  

 1 递归问路:
 2 
 3 import time
 4 
 5 person_list=['alex','wupeiqi','linhaifeng','zsc']
 6 def ask_way(person_list):
 7     print('-'*60)
 8     if len(person_list) == 0:
 9         return '根本没人知道'
10     person=person_list.pop(0)
11     if person == 'linhaifeng':
12         return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' %person
13 
14     print('hi 美男[%s],敢问路在何方' % person)
15     print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' % (person, person_list))
16     time.sleep(1)
17     res=ask_way(person_list)
18 
19 
20     print('%s问的结果是: %res' %(person,res))
21     return res
22 
23 res=ask_way(person_list)
24 print(res)
递归问路  

  递归特性:

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

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

    3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,

     每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,

     所以,递归调用的次数过多,会导致栈溢出)

 1 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
 2 
 3 
 4 def binary_search(dataset, find_num):
 5     print(dataset)
 6 
 7     if len(dataset) > 1:
 8         mid = int(len(dataset) / 2)
 9         if dataset[mid] == find_num:  # find it
10             print("找到数字", dataset[mid])
11         elif dataset[mid] > find_num:  # 找的数在mid左面
12             print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
13             return binary_search(dataset[0:mid], find_num)
14         else:  # 找的数在mid右面
15             print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid])
16             return binary_search(dataset[mid + 1:], find_num)
17     else:
18         if dataset[0] == find_num:  # find it
19             print("找到数字啦", dataset[0])
20         else:
21             print("没的分了,要找的数字[%s]不在列表里" % find_num)
22 
23 
24 binary_search(data, 66)
25 
26 
27 
28 
29 ##### 结果
30 [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
31 找的数在mid[18]右面
32 [20, 21, 22, 23, 30, 32, 33, 35]
33 找的数在mid[30]右面
34 [32, 33, 35]
35 找的数在mid[33]右面
36 [35]
37 没的分了,要找的数字[66]不在列表里
二分法

   

  作用域:

     函数的作用域只跟函数声明时定义的作用域有关,跟函数的调用位置无任何关系  

 1 name = 'jack'
 2   
 3 def foo():
 4     name = 'jerry'
 5     def bar():
 6         name = 'lucy'
 7         print(name)
 8         def tt():
 9             print(name)
10         return tt
11     return bar
12 
13 func = foo() # 得到的是bar()函数的内存地址
14 func()() # 执行bar() 函数
15 # 可以直接foo()()()

  匿名函数:

    匿名函数就是不需要显示的指定函数名。模式:lambda x:x+1   

 1 如下代码:
 2 def calc(x):
 3     return x+1
 4 calc(10)
 5 
 6 用匿名函数表示:
 7 func = lambda x:x+1
 8 print(func(10))
 9 
10 
11 
12 def test(x,y,z):
13      return x+1,y+1  #----->(x+1,y+1)
14 
15 匿名函数表示:
16 lambda x,y,z:(x+1,y+1,z+1)
    匿名函数主要用于和其他函数的搭配:
1 l=[3,2,100,999,213,1111,31121,333]
2 print(max(l))
3 
4 dic={'k1':10,'k2':100,'k3':30}
5 
6 
7 print(max(dic))
8 print(dic[max(dic,key=lambda k:dic[k])])
 1 res = map(lambda x:x**2,[1,5,7,4,8])
 2 for i in res:
 3     print(i)
 4 
 5 输出
 6 1
 7 25
 8 49
 9 16
10 64

 

  函数式编程:

    编程方法论:面向过程、面向对象、函数式

    面向过程:简单的说就是没有返回值,一层一层的往下传递,直到实现需求

    面向对象:把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为

    举例五子棋:

      面向过程:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。

      面向对象:1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。

   什么是函数式编程:函数式=编程语言定义的函数 + 数学意义的函数
        通俗来讲,函数式就是利用编程语言实现数学函数,这种函数内对象是永恒不变的,要么返回值是函数,要么参数是函数,
        没有for和while循环,所有的循环都用递归实现,没有变量赋值,即不改变。但是可读性低,很精简。
        
 1 一、不可变:没有变量,也就没有赋值和修改
 2 # 非函数式:
 3 a=1
 4 def foo():
 5     global a # 尽量啥用
 6     a = 2
 7     return a
 8 foo()
 9 print a
10 
11 # 函数式
12 a = 1
13 def foo():
14     return a+1
15 foo()
16 print a                
17 
18 ###高阶函数  1、函数接收的参数是一个函数名  2、返回值中包含函数
19 ###满足之一就是高阶函数
20 
21 二、函数即变量,把函数当做参数传递给另一个函数
22 def foo(n): #n=bar
23     print(n)
24 
25 def bar(name):
26     print('my name is %s' %name)
27 
28 foo(bar)
29 foo(bar()) #报错
30 foo(bar('alex'))
31 
32 
33 三、返回值中包含函数
34 def bar():
35     print('from bar')
36 def foo():
37     print('from foo')
38     return bar
39 n=foo()
40 n()
41 
42 
43 def hanle():
44     print('from handle')
45     return hanle
46 h=hanle()
47 h()
48 
49 
50 
51 def test1():
52     print('from test1')
53 def test2():
54     print('from handle')
55     return test1()
函数式编程样例分析

 1 四、尾调用:在函数的最后一步调用另一个函数(最后一行不一定是函数的最后一步)
 2 # 函数bar在foo内是尾调用
 3 def bar(n):
 4     return n 
 5 def foo(x):
 6     return bar(x)
 7 
 8 # 函数bar1和bar2在foo内是尾调用,二者在if判断条件不同的情况下都有可能作为函数的最后一步
 9 def bar1(n):
10     return n
11 def bar2(n):
12     return n+1
13 
14 def foo(x):
15     if type(x) is str:
16         return bar1()
17     else18         return bar2()
19 
20 
21 # 函数bar在foo内不是尾调用
22 def bar(n):
23     return n 
24 def foo(x):
25     y = bar(x)
26     return y
27 
28 # 函数bar在foo内不是尾调用
29 def bar(n):
30     return n 
31 def foo(x):
32     return bar(x) +1 # 先执行bar(x)完了还要执行+1操作 所以不是最后一步
函数式编程样例分析2
 1 背景:最后一步调用递归,不要不保存上一次的状态,直接进入下一次递归
 2 
 3 非尾递归
 4 def foo(seq):
 5     if len(seq) == 1:
 6         return seq[0]
 7     head,*tail=seq
 8     return head + foo(tail) #每次都用head保存状态
 9 print(foo(range(100)))
10 
11 尾递归
12 def cal(l):
13     print(l)
14     if len(l) == 1:
15         return l[0]
16     first,second,*args=1
17     1[0]=first*second
18     l.pop(1)
19     return cal(l)
尾递归优化例子

        高阶函数:(map。filter。reduce.....)

 1 #高阶函数 1、函数接收的参数是一个函数名  2、返回值中包含函数
 2 # 满足其一即可
 3 # 把函数当作参数传给另外一个函数
 4 # def foo(n): #n=bar
 5 #     print(n)
 6 #
 7 # def bar(name):
 8 #     print('my name is %s' %name)
 9 #
10 # foo(bar)
11 # foo(bar())
12 # foo(bar('alex'))
13 
14 #返回值中包含函数
15 # def bar():
16 #     print('from bar')
17 # def foo():
18 #     print('from foo')
19 #     return bar
20 # n=foo()
21 # n()
22 
23 def hanle():
24     print('from handle')
25     return hanle
26 h=hanle()
27 h()
28 
29 def test1():
30     print('from test1')
31 def test2():
32     print('from handle')
33     return test1()
View Code

        map函数: 

           map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

 1 num_l = [1, 2, 10, 5, 3, 7]
 2 def map_test(func, array):  # func=lambda x:x+1    arrary=[1,2,10,5,3,7]
 3     ret = []
 4     for i in array:
 5         res = func(i)  # add_one(i)
 6         ret.append(res)
 7     return ret
 8 print(map_test(lambda x: x + 1, num_l))
 9 
10 res = map(lambda x: x + 1, num_l) 
11 
12 ## 上面就是map函数的功能,map得到的结果是可迭代对象
13 print('内置函数map,处理结果', res)
14 print('内置函数map,处理结果', list(res))
15 
16 结果:
17 [2, 3, 11, 6, 4, 8]
18 内置函数map,处理结果 <map object at 0x002809F0>
19 内置函数map,处理结果 [2, 3, 11, 6, 4, 8]
20 
21 
22 map后面的参数是一个可迭代对象,执行map时,相当于执行一个for循环
23 
24 print(list(map(lambda x:x+'s','12123123')))
25 #['1s', '2s', '1s', '2s', '3s', '1s', '2s', '3s']
26 
27 print(list(map(lambda x:x+'s',{'a':1,'b':2})))
28 # ['as', 'bs']
map函数

 1 num_l = [1, 2, 10, 5, 3, 7]
 2 def map_test(func, array):  # func=lambda x:x+1    arrary=[1,2,10,5,3,7]
 3     ret = []
 4     for i in array:
 5         res = func(i)  # add_one(i)
 6         ret.append(res)
 7     return ret
 8 print(map_test(lambda x: x + 1, num_l))
 9 
10 res = map(lambda x: x + 1, num_l) 
11 
12 ## 上面就是map函数的功能,map得到的结果是可迭代对象
13 print('内置函数map,处理结果', res)
14 print('内置函数map,处理结果', list(res))
15 
16 结果:
17 [2, 3, 11, 6, 4, 8]
18 内置函数map,处理结果 <map object at 0x002809F0>
19 内置函数map,处理结果 [2, 3, 11, 6, 4, 8]
20 
21 
22 map后面的参数是一个可迭代对象,执行map时,相当于执行一个for循环
23 
24 print(list(map(lambda x:x+'s','12123123')))
25 #['1s', '2s', '1s', '2s', '3s', '1s', '2s', '3s']
26 
27 print(list(map(lambda x:x+'s',{'a':1,'b':2})))
28 # ['as', 'bs']
map函数

        -注-:

          map()函数不改变原有的 list,而是返回一个新的 list。

         利用map()函数,可以把一个 list 转换为另一个 list,只需要传入转换函数。

               由于list包含的元素可以是任何类型,因此,map() 不仅仅可以处理只包含数值的 list,事实上它可以处理包含任意类型的 list,只要传入的函数f可以处理这种数据类型。

 

1 def format_name(s):
2     # s1=s[0:1].upper()+s[1:].lower();
3     s1 = s.capitalize()
4     return s1;
5 
6 print(map(format_name, ['adam', 'LISA', 'barT']))
7 print(list(map(format_name, ['adam', 'LISA', 'barT'])))
map实现输入的名字首字母大写

 

       filter函数:

         filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。

 1 movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb']
 2 # def sb_show(n):
 3 #     return n.endswith('sb')
 4 #--->lambda n:n.endswith('sb')
 5 
 6 def filter_test(func,array):
 7     ret=[]
 8     for p in array:
 9         if not func(p):
10                ret.append(p)
11     return ret
12 
13 res=filter_test(lambda n:n.endswith('sb'),movie_people)
14 print(res)
15 
16 #filter函数
17 movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb']
18 print(filter(lambda n:not n.endswith('sb'),movie_people))
19 #<filter object at 0x01CFC850>
20 print(list(filter(lambda n:not n.endswith('sb'),movie_people)))
21 #['linhaifeng']
filter()函数

         -注-:

            filter()函数对list中的每一个元素带入f函数进行运算,保留返回结构为真的元素。

        reduce函数:

          reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。

 

 1 num_l=[1,2,3,100]
 2 def reduce_test(func,array,init=None):
 3     if init is None:
 4         res=array.pop(0)
 5     else:
 6         res=init
 7     for num in array:
 8         res=func(res,num)
 9     return res
10 
11 print(reduce_test(lambda x,y:x*y,num_l,100))
12 
13 
14 #reduce函数
15 # 使用reduce()函数先导入模块
16 from functools import reduce
17 num_l=[1,2,3,100]
18 print(reduce(lambda x,y:x+y,num_l,1)) #可以定义起始值,否则默认起始值为第一个元素
19 print(reduce(lambda x,y:x+y,num_l))
reduce()函数

      小结:

 

 1 #map()处理序列中的每个元素,得到的结果是一个‘列表’,该‘列表’元素个数及位置与原来一样
 2 #
 3 
 4 #filter遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来
 5 
 6 people=[
 7     {'name':'alex','age':1000},
 8     {'name':'wupei','age':10000},
 9     {'name':'yuanhao','age':9000},
10     {'name':'linhaifeng','age':18},
11 ]
12 print(list(filter(lambda p:p['age']<=18,people)))
13 
14 
15 #reduce:处理一个序列,然后把序列进行合并操作
16 from functools import reduce
17 print(reduce(lambda x,y:x+y,range(100),100))
18 print(reduce(lambda x,y:x+y,range(1,101)))
小结

 

 

 

    

  

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Python 全栈开发:python字符串切片

下一篇:Pycharm快捷键