1.匿名函数
用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。
sum = lambda arg1, arg2: arg1 + arg2
# 调用sum函数
print("Value of total : %s" % sum( 10, 20 ))
print("Value of total : %s" % sum( 20, 20 ))
2.列表推导式
所谓的列表推导式,就是指的轻量级循环创建列表
a = [x for x in range(1,101)]
b = [a[x:x+3] for x in range(0,len(a),3)]
print(a)
print(b)
列表推导式也可以实现多个for循环
c = [(x,y,z) for x in range(1,3) for y in range(3) for z in range(4,6)]
print(c)
输出:[(1, 0, 4), (1, 0, 5), (1, 1, 4), (1, 1, 5), (1, 2, 4), (1, 2, 5), (2, 0, 4), (2, 0, 5), (2, 1, 4), (2, 1, 5), (2, 2, 4), (2, 2, 5)]
3.映射函数
Python map()
内置函数将给定函数应用于可迭代的每一项,并返回一个迭代器对象。参考文献
nums = [1, 2, 3, 4, 5]
nums_squared = map(lambda x: x*x, nums)
for num in nums_squared:
print(num)
输出:
1
4
9
16
25
映射函数的等价实现
def square(x):
return x * x
def mymap(func, iterable):
for i in iterable:
yield func(i)
nums = [1, 2, 3, 4, 5]
nums_squared = mymap(square, nums)
for num in nums_squared:
print(num)
4.迭代器对象
迭代器对象是内置有iter和next方法的对象,打开的文件本身就是一个迭代器对象。
执行迭代器对象 .iter() 方法得到的仍然是迭代器本身。
执行迭代器 .next() 方法就会计算出迭代器中的下一个值。
当我们已经迭代完最后一个数据之后,再次调用next()函数会抛出StopIteration的异常,来告诉我们所有数据都已迭代完成,不用再执行next()函数了。
numList=[1,2,3,4,5]
i=iter(numList) #每次都需要重新获取一个迭代器对象
while True:
try:
print(next(i))
except StopIteration: #捕捉异常终止循环
break
输出:
1
2
3
4
5
5.生成器对象
利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成。但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据。为了达到记录当前状态,并配合next()函数进行迭代使用,我们可以采用更简便的语法,即生成器(generator)。生成器是一类特殊的迭代器。
生成器是一个返回迭代器的函数,只能用于迭代操作,可理解为生成器就是一个自定义迭代器。
- 使用了yield关键字的函数不再是函数,而是生成器。(使用了yield的函数就是生成器)
- yield关键字有两点作用:
- 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
- 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
- 可以使用next()函数让生成器从断点处继续执行,即唤醒生成器(函数)
- Python3中的生成器可以使用return返回最终运行的返回值
5.1 举例(精简代码)
使用了 yield 的函数被称为生成器(generator)。
def fib(n):
current = 0
num1, num2 = 0, 1
while current < n:
num = num1
num1, num2 = num2, num1+num2
current += 1
yield num
return 'done'
F = fib(5)
print(F)
输出:<generator object fib at 0x000001AC3089E390>
5.2 举例(流式内存)
因为迭代器不会保存所有值,而是在运行中动态的计算出数列的各个值,并将之前的数值扔掉。
所以可以对大文件使用 yield 构造生成器进行流式读取。
def read_by_chunks(file, chunk_size=1024):
while True:
data = file.read(chunk_size)
if not data:
break
yield data
f = open('your_big_file.dat')
for chunk in read_by_chunks(f):
process_chunk(chunk)
这种通过构造生成器逐块读取的方法叫做惰性加载,也叫流式读取,是处理大文件的一种常见方式。
注:常见的文本文件的读取,就是上述读取方法的一个简单案例。
with open('your_big_file.txt') as f:
for line in f:
process_line(line)
6.闭包
闭包,一句话说就是,在函数中再嵌套一个函数,并且引用外部函数的变量,这就是一个闭包。
# 定义一个函数
def test(number):
# 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
def test_in(number_in):
print("in test_in 函数, number_in is %d" % number_in)
return number+number_in
# 其实这里返回的就是闭包的结果
return test_in
案例:
# 闭包
def line_conf(a, b):
def line(x):
return a*x + b
return line
line1 = line_conf(1, 1)
print(line1)
print(line1(5))
输出:
<function line_conf..line at 0x000002AF3421B8C8>
6
7.装饰器
装饰器就是一个闭包,装饰器是闭包的一种应用。
python装饰器就是用于拓展原来函数功能的一种函数。
这个函数的特殊之处在于它的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def now():
print(datetime.datetime.now())
now()
输出:
call now():
2022-03-28 22:56:41.291046