1.列表推导式
列表推导式:可以快速生成一个列表。
用法: 变量 = [ 推到语句 ]
例 1. 得到1~100的列表
>>> ls = [x for x in range(1,101)] # 推导式
>>> ls
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 2
5, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99, 100]
例 2. 得到1~100 2的倍数的列表
>>> ls = [x for x in range(1,101) if x % 2 == 0] #推导式
>>> ls
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46,
48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 9
2, 94, 96, 98, 100]
注意:到需要生成大量元素时,空间浪费就会常大。
2.列表生成器
列表生成器与列表推导式相比 就是把 [ ]换成(),切返回的是一个对象。当需要拿出元素时需用
借助next(对象)来拿出元素。
next ----相当于指针 ,拿出一个之后不会回退(意思是每个元素只能拿一次),直到超出元素个数后抛出错误。
例 1. 1~5的列表生成
>>> ls = (x for x in range(1,6)) #生成器
>>> next(ls)
1
>>> next(ls)
2
>>> next(ls)
3
>>> next(ls)
4
>>> next(ls)
5
>>> next(ls)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
通过遍历的方式也可以拿出元素
>>> ls = (x for x in range(1,6))
>>> for i in ls:
... print(i)
...
1
2
3
4
5
例 2. 将函数转换为推导式。
ls = []
def fibonacci(num):
one = 1
two = 1
index = 0
while index<= num:
ls.append(one)
one ,two = two , two + one
index += 1
if __name__ == '__main__':
fibonacci(5)
print(ls)

但是这样元素会一直存储在列表中,也会照成空间的大量浪费。因此需要用到yield关键字,返回的是一个生成器,减少了空间的浪费。
yield关键字与return 相似都是返回值。但又有所不同,yield 返回的是一个对象(生成器),return 返回的是一个值。因此一般在取值的时候会用 next() 或是 遍历 来获取元素。
例 1.斐波那契数
def fibonacci(num):
one = 1
two = 1
index = 0
while index<= num:
one ,two = two , two + one
yield one
index += 1
if __name__ == '__main__':
ls = fibonacci(5)
print(next(ls))
print("\n")
for i in ls: #如果用遍历取元素,会比较方便。
print(i)

yield ----不仅返回的是一个对象(生成器),记住上次的位置执行从上次结束的位置开始。
def CheShi(num):
print("---start---")
index = 0
while index <= num:
print("---1---")
yield "记住这次位置"
print("----2----")
if __name__ == '__main__':
ls =CheShi(5)
print(next(ls))

增加以次 next关键字,取值之后。

2.迭代器
迭代(Itreable)是访问容器元素的一种方式 。可迭代的对象有哪些?------可以用for in 循环进行遍历的对象基本都可以迭代除此之外还可以使用isinstance()判断对象是否可迭代。在使用isinstance()时需要导入collections.abc库中的Iterable.
isinstance(对象,Iterable)---入过对象可迭代 返回True
例 1.
>>> from collections.abc import Iterable
>>> ls = "ahahahah"
>>> a = 10
>>> isinstance(ls,Iterable)
True
>>> isinstance(a,Iterable)
False
凡是能被next()调用,并返回值得才是迭代器,但前提是对象必须可迭代。可迭代的不一定是迭代器,迭代器一定可迭代
判断是不是迭代器 isinstance(对象,Iterator),如果是则返回True ,Iterator也是colletcions.abc库中的也需要导入。
例,
>>> from collections.abc import Iterator
>>> ls = "ahahah"
>>> ls1 = 10101
>>> ls2 = ("1",1,23)
>>> isinstance(ls,Iterator)
False
>>> isinstance(ls1,Iterator)
False
>>> isinstance(ls2,Iterator)
False
>>> ls3 = [1,2,3,4,"5"]
>>> isinstance(ls3,Iterator)
False
迭代器是可以转化为迭代器的,需要用到一个全局函数,iter().用法 iter(可迭代的对象) 返回的是一个对象 ,一般需要用变量来接受这个对象
>>> from collections.abc import Iterator
>>> ls = "ahahha"
>>> ls1 = 10101
>>> ls2 = [1,2,3,4,"5"]
>>> ls3 = ("1",1,23)
>>> ls_s = iter(ls)
>>> isinstance(ls_s,Iterator)
True
>>> ls1_s = iter(ls1) #ls1是一个int类型,不是可迭代对象,因此会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> ls2_s = iter(ls2)
>>> isinstance(ls2_s,Iterator)
True
>>> ls3_s = iter(ls3)
>>> isinstance(ls3_s,Iterator)
True
总结:凡是能用for循环遍历的对象是可迭代的,但是可迭代的并不一定是迭代器,但是迭代器一定是可迭代的,可迭代的对象可以通过iter(可迭代对象)转换为迭代器。迭代器还有一个重要特征就是能别next调用并返回值。
3.闭包
闭包是一种现象,弱数据语言特有的特征,闭包在python用的并不是很多,在js中用的频繁,但还是须要有所了解的。
闭包的概念:闭包其实就是函数中包裹的函数的现象就是闭包(函数中的变量只能作用于函数中(局部变量))
例.
def sum():
a = 10
def number():
b = 10
c = a + b
print(c)
return number #这里return返回的是number的地址
res = sum()
print(res)
res()

函数调用的本质是压栈的过程,res = outer() 调用了outer()函数的时候就是一个压栈的过程,当执 行完print(res)之后就会进行弹栈的操作,函数的局部变量就会被垃圾回收机制回收,但是inner()函数里 面要使用变量a,如果按照正常流程进行回收了,那么就会报错,但是并没有报错,那也就说明变量a没 有被回收
结论:闭包让外围的函数常驻内存,导致拦击不能及时释放,但是让局部变量变成了全局变量,所 以说尽量不要使用闭包,在js中闭包使用的比较广泛,而在python中比较少,会用在装饰器中
4.装饰器
装饰器是闭包的应用的一种,装饰器可以在不改变原有代码的基础上增加新的功能。
用法: 通过 @函数名 用在需要增加功能的函数前面
例. 无参
def outer(fn):
def a():
print("验证语句1")
fn()
return a
@outer
def f1():
print("功能语句!")
if __name__ == '__main__':
f1()

此例子是一个简写例子,意表现装饰器的用途。
注意在用装饰器时,闭包函数有一个参数是必须要有的,不管被装饰的函数是否有参数都要写上@outer加在被装饰的函数的前面就相当于将函数吃掉了,outer(fn)-----这个fn就相当于是被装饰的函数体。
例.当被装饰的函数有参数时
def outer(fn):
def a(user,password):
#def a (g,h):
print("验证语句1")
fn(user,password)
#fn(g,h)
return a
@outer
def f1(user,password):
print("user={},password = {}".format(user,password))
if __name__ == '__main__':
user = "林林"
password = 113223
f1(user,password)

当被装饰的函数体有参数时,在闭包中的函数也应该跟上相同个数的形参(形参的并不一定需要一模一样,个数相同就行)
本文介绍了Python中的列表推导式、列表生成器、迭代器和闭包,展示了如何通过这些高级特性快速创建和操作列表,同时强调了空间效率和闭包在特定场景的应用。
324





