python:匿名函数、filter和map函数、partial偏函数、递归函数、生成器

函数参数
只有一个参数名,称作位置参数
参数形式时key=value,称作关键字参数

>>> def get_age(name, age):
...    print('%s is %s years old' % (name, age))
... 
>>> get_age('bob', 20)
bob is 20 years old

>>> get_age()		#Error,参数太少
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: get_age() missing 2 required positional arguments: 'name' and 'age'
>>> get_age('bob', 20, 100)		#Error,参数太多
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: get_age() takes 2 positional arguments but 3 were given
>>> get_age(20, 'bob')		#语法正确,但是语义错误
20 is bob years old
>>> get_age(age=20, name= 'bob')		#ok
bob is 20 years old
>>> get_age(age=20, 'bob')		#Error,关键字参数必须在后
  File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>> get_age(20, name= 'bob')		#Error,name得到了多个值
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: get_age() got multiple values for argument 'name'
>>> get_age('bob', age=20)		#ok
bob is 20 years old

参数组
如果函数的参数个数是不固定的,可以使用参数组接收参数

• python允许程序员执行一个没有显式定义参数的函数
• 相应的方法是通过一个把元组(非关键字参数)或字典(关键字参数)作为参数组传递给函数

— 在参数名前加"*“表示参数是元组
— 在参数名前加”**"表示参数是字典

>>> def func1(*args):
...   print(args)
... 
>>> func1()
()
>>> func1('bob')
('bob',)
>>> func1('bob', 123, 'hello', 'aaa')
('bob', 123, 'hello', 'aaa')
>>> def func2(**args):
...   print(args)
... 
>>> func2()
{}
>>> func2(name ='bob', age=20)
{'name': 'bob', 'age': 20}

调用函数时,如果参数有“*”,表示把参数拆开
>>> def add(x, y):
...   print(x+y)
... 
>>> nums = [10, 20]
>>> num_dict = {'x': 10, 'y': 20}
>>> num_dict2 = {'a': 10, 'b': 20}
>>> add(nums)		#Error,参数nums赋值给了x,y没有得到值
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() missing 1 required positional argument: 'y'
>>> add(num_dict)		#Error,参数nums赋值给了x,y没有得到值
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() missing 1 required positional argument: 'y'
>>> add(*nums)		# nums拆成了10, 20
30
>>> add(**num_dict)		# 拆成了x=100, y=200
30
>>> add(**num_dict2)		# 拆成了a=100, b=200,与函数定义的形参名不符
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() got an unexpected keyword argument 'a'

匿名函数
—如果函数的代码块非常简单,只有一行,可以使用匿名函数。
—匿名函数使用lambda关键字定义。

在这里插入图片描述

>>> def add(x, y):
...   return x + y
... 
>>> add(10, 20)
30
>>> myadd = lambda x, y: x + y
>>> myadd(10, 20)
30

[root@room9pc01 day07]# vim math_game3.py
from random import randint, choice

def exam():
    cmds = {'+': lambda x, y: x + y, '-': lambda x, y: x-y}		#使用匿名函数传值
    nums = [randint(1, 100) for i in range(2)]
    nums.sort(reverse = True)  #降序排列
    op = choice('+-')
    result = cmds[op](*nums)

    prompt ='%s %s %s = ' % (nums[-2], op, nums[-1])
    counter = 0
    while counter < 3:
        try:
            answer = int(input(prompt))
        except:		#不指定异常默认捕获所有异常,但是不推荐
            print()
            continue

        if answer == result:
            print('Very Good!')
            break

        print('Answer Wrong !')
        counter += 1
    else:
        print('%s %s' % (prompt, result))

if __name__ == '__main__':
    while True:
        exam()
        try:
            yn = input('Continue(y/n)? ').strip()[0]    #删除用户输入的多余空格,并取出第一个字符
        except IndexError:
            yn = 'y'
        except (KeyboardInterrupt, EOFError):
            yn = 'n'

        if yn in 'nN':
            print('\nBye-bye')
            break

filter和map函数
在这里插入图片描述
在这里插入图片描述

[root@room9pc01 day07]# vim filter_func.py
ffrom random import randint

def func1(x):
    return True if x > 50 else False

def func2(x):
    return x +2

if __name__ == '__main__':
    nums = [randint(1,100) for i in range(10)]
    print(nums)
    result =filter(func1, nums)
    print(list(result))
    result2 = filter(lambda x: True if x > 50 else False, nums)
    print(list(result2))
    result3 = map(func2, nums)
    print(list(result3))
    result4 = map(lambda x: x+2, nums)
    print(list(result4))
[root@room9pc01 day07]# python3 filter_func.py
[34, 3, 74, 31, 94, 81, 38, 13, 20, 57]
[74, 94, 81, 57]
[74, 94, 81, 57]
[36, 5, 76, 33, 96, 83, 40, 15, 22, 59]
[36, 5, 76, 33, 96, 83, 40, 15, 22, 59]

filter和map函数赋值时只能使用一次

>>> nums = filter(lambda x: x%2==0, [i for i in range(10)])
>>> nums
<filter object at 0x7fd566ab3668>		#filter函数对象
>>> list(nums)
[0, 2, 4, 6, 8]
>>> list(nums)
[]
>>> nums = map(lambda x: x+2, [i for i in range(10)])
>>> nums
<map object at 0x7fd566ab3668>		#map函数对象
>>> list(nums)
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> list(nums)
[]
>>> nums = map(lambda x: x+2, [i for i in range(10)])
>>> ab =list(nums)
>>> ab
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> ab
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
>>> abc= list(nums)
>>> abc
[]

全局变量
在函数外面定义的变量。从定义起始位置开始,一直到程序结束,任何地方均可见可用。

局部变量
在函数内部定义的变量。只在函数内部使用,离开函数不能使用。函数的参数也可以看作是局部变量。

>>> x = 10		#x为全局变量
>>> def func1():
...   print(x)
... 
>>> func1()
10
>>> def func2():
...   x = 'hello'		#x为局部变量,局部和全局有相同的变量,局部遮盖住全局变量
...   print(x)
... 
>>> func2()
hello
>>> x
10
>>> def func3():
...   global x		# 声明函数内部使用的是全局变量x
...   x = 'ni hao'
...   print(x)
... 
>>> func3()
ni hao
>>> x
'ni hao'

名称查找的时候,先查局部,再查全局,最后查内建。
>>> def func4():
...   print(len('abc'))
... 
>>> func4()		#查到了内建len函数
3
>>> len = 10
>>> func4()		#在全局查到len的值是10,数字不能调用
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in func4
TypeError: 'int' object is not callable

partial偏函数
在这里插入图片描述

>>> from functools import partial
>> add(10, 20, 30, 40, 50)
150
>>> add(10, 20, 30, 40, 9)
109
>>> add(10, 20, 30, 40, 15)
115
>>> myadd = partial(add, 10, 20, 30, 40)
>>> myadd(50)
150
>>> myadd(9)
109
>>> myadd(15)
115

案例:简单GUI程序
在这里插入图片描述

[root@room9pc01 day07]# vim mygui.py		//编写gui程序
import tkinter
from functools import partial

window = tkinter.Tk()
lb = tkinter.Label(window, text = 'Hello World', font= 'Arial 20')
#b1 = tkinter.Button(window, fg='white', bg='blue', text='Button 1')
#b2 = tkinter.Button(window, fg='white', bg='blue', text='Button 2')
#b3 = tkinter.Button(window, fg='white', bg='blue', text='quit', command=window.quit)
MyButton = partial(tkinter.Button, window, fg='white', bg='blue')
b1 = MyButton(text='Button 1')
b2 = MyButton(text='Button 1')
b3 = MyButton(text='quit', command=window.quit)
lb.pack()
b1.pack()
b2.pack()
b3.pack()
window.mainloop()

递归函数
• 如果函数包含了对其自身的调用,该函数就是递归的
• 在操作系统中,查看某一目录内所有文件、修改权限等都是递归的应用

[root@room9pc01 day07]# vim fun_jiecheng.py		//阶乘程序计算n!
def func(n):
    if n == 1:
        return 1
    return n*func(n-1)

if __name__ == '__main__':
    print(func(5))
[root@room9pc01 day07]# python3 fun_jiecheng.py		//计算5的阶乘5!
120

快速排序:
假定第一个数是中间值。把比这个数小的放到smaller列表,把比它大的数放到larger列表。最后把这三个部分拼接起来。smaller和larger采用相同的办法继续排序,直到列表的长度是0或1结束。
[root@room9pc01 day07]# vim qsort.py		//编写程序,在1—100之间随机取10个数,并按从小到大顺序排序
from random import randint

def qsort(seq):
    if len(seq) < 2:        #如果长度小于2,不用排序,直接返回
         return seq

    middle = seq[0]     #假定第一个值是中间值
    smaller = []        #用于保存比中间值小的数据
    larger = []         #用于保存比中间值大的数据

    for i in seq[1:]:
        if i < middle:
            smaller.append(i)
        else:
            larger.append(i)

    return qsort(smaller) + [middle] +qsort(larger)

if __name__ == '__main__':
    nums = [randint(1, 100) for i in range(10)]
    print(nums)
    print(qsort(nums))
[root@room9pc01 day07]# python3 qsort.py		//程序演示
[44, 96, 7, 52, 76, 35, 10, 55, 68, 76]
[7, 10, 35, 44, 52, 55, 68, 76, 76, 96]

生成器

  • 生成器本质上也是函数。和普通函数不同,普通函数只能通过return返回一个值,但是生成器可以通过yield返回多个中间值。
  • 生成器对象只能使用一次。
>>> def mygen():			#定义生成器函数
...   yield 'hello'			#生成器函数通过yield返回值
...   yield 50
...   yield 'a+b'
...   a = 10 + 20
...   yield a
... 
>>> mg = mygen()
>>> mg
<generator object mygen at 0x7fd56e22cbf8>
>>> list(mg)			#将生成器对象转换为列表
['hello', 50, 'a+b', 30]
>>> list(mg)			#生成器对象只能使用一次
[]
>>> mga = mygen()		#通过赋值值生成器函数,可以重复获取生成器对象
>>> mga
<generator object mygen at 0x7fd56e22cc50>		#表明为生成器对象,占用内存空间小
>>> list(mga)
['hello', 50, 'a+b', 30]
>>> for  i in mga:		#上一条命令使用了一次生成器对象,无法遍历
...   print(i)
... 
>>> mga = mygen()
>>> for  i in mga:		#重新赋值生成器对象,for循环可以遍历
...   print(i)
... 
hello
50
a+b
30

生成器还可以使用生成器表达式

>>> from random import randint
>>> nums = (randint(1, 100) for i in range(10))		#生成器表达式
>>> nums
<generator object <genexpr> at 0x7fd566a8feb8>		#生成器对象
>>> list(nums)
[5, 17, 84, 16, 22, 4, 48, 22, 87, 67]
>>> list(nums)
[]
>>> ips = ('192.168.8.%s' % i for i in range(1, 5))
>>> ips
<generator object <genexpr> at 0x7fd566a8ffc0>		#生成器对象
>>> for ip in ips:
...  print(ip)
... 
192.168.8.1
192.168.8.2
192.168.8.3
192.168.8.4
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值