filter 函数¶
- 过滤函数: 对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回
- 跟map相比:
- 相同点:对列表的每一个元素进行操作
- 不同点:
- map会生成一个与原来数据相对应的新队列
- filter不一定,只有符合条件才能进入新的数据集合
- filter函数:
- 利用给定函数进行判断
- 返回值一定是bool
- 调用格式:filter(f,data),f是过滤函数,data为数据
In [8]:
#filter案例
#对一个列表进行过滤,只要偶数
def Isdou(n):
return n%2==0
l = [12,23,456,4,23,7,453,6,865,3,347,58,43,347,32]
rst = filter(Isdou,l)
print(rst)
print(type(rst))
print([i for i in rst])
<filter object at 0x7fbecc187128> <class 'filter'> [12, 456, 4, 6, 58, 32]
高阶函数-排序
- 把一个序列按照给定的算法排序
- key: 在排序前对每一个元素进行key函数运算
-
sorted 语法:
- sorted(iterable[, cmp[, key[, reverse]]])
-
参数说明:
- iterable -- 可迭代对象。
- cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
- key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
- reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
- 返回值
- 返回重新排序的列表。
In [9]:
#排序案例
a = [123,35,678,23,6785,2343,67,1,444,245]
al = sorted(a,reverse=True)
print(al)
[6785, 2343, 678, 444, 245, 123, 67, 35, 23, 1]
In [11]:
#排序案例2
a = [-323,34325,-346345,232,-54,678]
al = sorted(a,key=abs,reverse=True)##abs指的是绝对值,即 按照绝对值降序排列
print(al)
[-346345, 34325, 678, -323, 232, -54]
In [12]:
#排序案例3
asr = ['Avds','asf','avds','hahaha']
str1 = sorted(asr)
print(str1)
str2 = sorted(asr,key=str.lower)
print(str2)
['Avds', 'asf', 'avds', 'hahaha'] ['asf', 'Avds', 'avds', 'hahaha']
返回函数
- 函数可以返回具体的值
- 也可以返回一个函数作为结果
In [16]:
#普通函数
def Haa(a):
print('hahahah')
return None
a = Haa('q')
print(a)
hahahah None
In [19]:
#函数作为返回值返回,被返回的函数在函数体内定义
def Myfu1():
def Myfu2():
print('In Myfu1')
return 2
return Myfu2
#调用函数
#调用Myfu1,返回一个函数Myfu2,赋值给f3
f3 = Myfu1()
print(type(f3))
print(f3)
f3()
<class 'function'> <function Myfu1.<locals>.Myfu2 at 0x7fbecc9e77b8> In Myfu1
Out[19]:
2
In [21]:
#返回函数例子
#args:参数列表
#1.myF3定义函数,返回内部定义的函数myF4
#2.myF4使用外部变量,这个变量是myF3的参数
def myF3(*args):
def myF4():
n = 0
for i in args:
n += i
return n
return myF4
f4 = myF3(1,2,3,4,5,6,7,8,9,0)
f4()
Out[21]:
45
闭包(closure)
- 当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当外部函数被当做返回值的时候,相关参数被保存在返回函数中,这种结果叫闭包
- 如上述函数myF3
In [23]:
#闭包常见的坑
def count ():
#定义列表,列表里存放的是定义的函数
fs =[]
for i in range(1,4):
#f为一个闭包结构
def f():
return i*i
fs.append(f)
return fs
f1,f2,f3 = count()
print(f1())#代表第一次循环,按理说该返回1 1*1
print(f2())#代表第二次循环,按理说该返回4 2*2
print(f3())#代表第三次循环,按理说该返回9 3*3
9 9 9
出现上述问题原因:返回函数引用变量i,i并非立即执行,而是等到三个函数都返回的时候才统一使用,这时的i已经变成3,最终调用时返回值都为3*3
返回闭包时,返回函数不能引用任何循环变量
解决方案: 再创建一个函数,用该函数的参数绑定循环变量当前值,无论循环变量如何改变,已绑定函数参数值不再改变
In [28]:
def count2():
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 = count2()
print(f1())
print(f2())
print(f3())
1 4 9
装饰器
- 实质
- 他们是修改其他函数的功能的函数,一旦定义可以修饰任何函数。
- 他们有助于让我们的代码更简短,也更Pythonic(Python范儿)。
- 不改动原有代码,实现新功能
- 一个返回函数的高阶函数
- 使用
- 在每次要扩展到函数定义前使用@+函数名
- 使用场景
- 授权(Authorization)
- 日志(Logging)
In [31]:
#实例
#对Hello函数进行功能扩展,在每次打印时输出时间
import time
#高阶函数
def PrintTime (f):
def war(*args, **Kwargs):
print('Time :',time.ctime())
return f(*args, **Kwargs)
return war
#使用装饰器时需要用@,即语法糖
@PrintTime
def Hello ():
print('Hello world!')
Hello()
Time : Thu Dec 27 08:36:10 2018 Hello world!
In [52]:
# 不使用语法糖,手动执行修饰器
def Hello1():
print('我是手动的')
Hello1 = PrintTime(Hello1)
Hello1()
p = PrintTime(Hello1)
p()
Time : Thu Dec 27 08:48:49 2018 我是手动的 Time : Thu Dec 27 08:48:49 2018 Time : Thu Dec 27 08:48:49 2018 我是手动的
偏函数(Partial function)
- 参数固定的函数,相当于一个有特定参数的函数体
- functools.partial的作用是把一个函数的某些函数固定,返回一个新函数
- partial(func,args, *keywords)
In [54]:
#把字符串转化为十进制数字
int('12345')
##把八进制字符串转化为十进制数字
int('12345',base = 8) #base代表几进制
Out[54]:
5349
In [66]:
#新建一个函数,输入字符串为十六进制,返回十进制
def int16(x,base=16):
return int(x,base)
int16('12345')
Out[66]:
74565
In [67]:
#偏函数实例
import functools
#实现上面int16的功能
int17 = functools.partial(int,base = 16)
int17('12345')
Out[67]:
74565