Python系统学习第二十课

filter 函数

  • 过滤函数:对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回
  • 跟map相比较
    • 相同,都对列表的每一个元素逐一进行操作
    • 不同:
      • map会生成一个跟原来数据相对应的新队列
      • filter不一定,只要符合条件的才会进入新的数据集合
    • filter函数怎么写
      • 利用给定函数进行判断
      • 返回值一定是一个布尔值
      • 调用格式:filter(f,data),f是过滤函数,data是数据
#filter案例
#对于一个列表,进行过滤,偶数组成一个新列表

#需要定义过滤函数
#过滤函数要求有输入,返回布尔值
def isEven(a):
    return a%2 == 0
l = [1,2,15,564,1,5,84,45,584,41,511]
s = filter(isEven, l)
#返回的filter内容是一个可迭代对象
print([i for i in s])
[2, 564, 84, 584]

高阶函数- 排序

  • 把一个序列按照给定算法进行排序
  • key:在排序前对每一个元素进行key函数运算,可以理解成按照key函数定义的逻辑进行排序
  • python2 和 3有区别
# 排序案例
a = [211,3454,561,54,5,654,548,65,42,48,5464,54,684,8,84]
a1 = sorted(a)
#倒着排
a2 = sorted(a,reverse = True)
print(a1)
print(a2)
[5, 8, 42, 48, 54, 54, 65, 84, 211, 548, 561, 654, 684, 3454, 5464]
[5464, 3454, 684, 654, 561, 548, 211, 84, 65, 54, 54, 48, 42, 8, 5]
#按照绝对值进行排序
a = [-211,3454,-561,54,-5,654,548,-65,42,-48,5464,-54,684,-8,84]
#按照绝对值排序
a2 = sorted(a,key=abs,reverse = True)
print(a2)
[5464, 3454, 684, 654, -561, 548, -211, 84, -65, 54, -54, -48, 42, -8, -5]
#sorted案例
astr = ['lizi', 'Yuhk', 'ased','Asderf','ojjug']
str1 = sorted(astr)
print(str1)

str2 = sorted(astr, key=str.lower)   #大小写不同排序
print(str2)
['Asderf', 'Yuhk', 'ased', 'lizi', 'ojjug']
['Asderf', 'ased', 'lizi', 'ojjug', 'Yuhk']

返回函数

  • 函数可以返回具体的值
  • 也可以返回一个函数作为结果
#定义一个普通函数
def yy(a):
    print(a)
    return None
a = yy(3)
print(a)
3
None
#函数作为返回值语句,被返回的函数在函数体内定义
def qq():
    def ww():
        print("qqqqq")
        return 2
    return ww

a = qq()   #调用函数qq,返回一个函数ww,赋值给a

print(a)
<function qq.<locals>.ww at 0x000002BECF11D620>
#复杂一点的返回参数的例子
#args:参数列表
#
def qq(*args):
    def ww():
        s = 0
        for i in args:  #使用了函数qq的参数
            s += i
        return s
    return ww
f5 = qq(1,2,3,4,5,6)
print(f5())
21

闭包(closure)

  • 当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当内部函数被当做返回值的时候,相关参数和变量保存在返回的函数中,这种结果,叫做闭包(如上边的例子,是一个标准的闭包结构)
#闭包常见的坑
def count():
    #定义列表
    fs = []
    for i in range(1,4):
        def f():
            return i*i
        #f是一个闭包结构
        fs.append(f)
    return fs
f1,f2,f3 = count()
print(f1())
print(f2())
print(f3())
9
9
9

#上边出现的问题

  • 造成上述状况的原因是,返回函数引用了变量i,i并非是立即执行,而是等到三个函数都返回的时候才统一使用,此时i已经变成了3,最终调用的时候,都返回的是3*3
  • 此问题描述成:返回闭包时,返回函数不能引用任何循环变量
  • 解决方案:再创建一个函数,用该函数的参数绑定循环变量的当前值,无论该循环变量以后如何改变,已经绑定的函数值不再改变
#修改上述函数
def count1():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1,4):
        fs.append(f(i))
    return fs
f1,f2,f3 = count1()
print(f1())
print(f2())
print(f3())

装饰器(decrator)

  • 在不改动函数代码的基础上无限制扩展函数功能的一种机制,本质上讲,装饰器是一个返回函数的高阶函数
  • 装饰器的使用:使用@语法,即在每次扩展到函数定义前使用@+函数名
def hello():
    print("hello world!")
hello()
hello world!
f = hello  #函数名就是变量
f()
hello world!
#f 和 hello 是一个函数
print(id(f))
print(id(hello))
print(f.__name__)

3018541095248
3018541095248
hello
#现在有新的需求:
#对hello功能进行扩展,每次打印hello之前打印当前系统时间
#而实现这个功能又不能改动现有代码
#==>使用装饰器
import time
#高阶函数,以函数作为参数
def printTime(f):   #把想被装饰的函数传进去
    def wrapper(*args, **kwargs):
        print("Time:",time.ctime())
        return f(*args, **kwargs)
    return wrapper
#上边定义了装饰器,使用的时候需要用到@,此符号是python的语法
@printTime
def hello():
    print("hello, world!")
    
hello()    #为什么不能打印helloworld出来???????????????
Time: Mon Dec 31 13:00:20 2018
hello, world!
  • 装饰器的好处,一点定义,则可以装饰任意函数
  • 一旦被装饰,则可以把装饰器的功能直接添加到定义函数的功能上
@printTime
def hello2():
    print("qqqq")
    print("wwwwww")
    
hello2()
Time: Mon Dec 31 13:00:22 2018
qqqq
wwwwww
# 上面对函数的装饰使用了系统定义的语法
# 下面开始手动执行下装饰器
#先定义函数
def hello3():
    print("wwww")
hello3 = printTime(hello3)
hello3()
Time: Mon Dec 31 13:05:02 2018
wwww

偏函数

  • 参数固定的函数,相当于一个有特定参数的函数体
  • functools.partial的作用是,把一个函数某些参数固定,返回一个新函数
#把字符串转化成十进制数字, int("123456")
int("123456")

123456
#- 求八进制的字符串12345,表示成十进制的数字是多少?
int("12345", base =8)
5349
#新建一个函数,此函数是默认输入的字符串是16进制的数字
#此字符串返回十进制的数字
def int16(x, base =16):
    return int(x, base)
int16("12345")
74565
import functools
#实现上面的int16的功能
int16 = functools.partial(int, base =16)
int16("12345")
74565
import functools
#实现上面int16 的功能
int16 = functools.partial(int, base=16)

int16("12345")
74565

猜你喜欢

转载自blog.csdn.net/qq_42633819/article/details/85692833