python基础学习day12 生成器与推导式
补充:函数不能改变全局不可变的变量,可变变量仍然可改变。
l1 = [1,2]
def a(l1):
l1.pop(1)
a(l1)
print(l1)
-
生成器
-
生成器:python社区把生成器与迭代器看成同一种,生成器的本质就是迭代器。唯一的区别是:生成器是我们自己用python代码构建的数据结构,迭代器都是python提供的,或者转化的。
-
获取生成器的方法:
- 生成器函数
- 生成器表达式
- python内部提供的。
-
生成器函数获取生成器,yield:
def func(): print(1) print(3) yield 5 print(func) #<function func at 0x000001A3CCA04438> 仍然是一个函数 ret = func() print(ret) #<generator object func at 0x000002471A631D48> #generator object#生成器对象
def func(): print(3) yield 5 ret = func() print(next(ret)) #3 5
#一个next对一个yield的返回值 def func(): print(3) yield 5 yield 7 print(next(func())) #3 5
-
yield与return
return:一个函数中只能存在一个return结束函数的调用,并且给函数的执行者返回值。
yield:只要函数中有yield那么它就是生成器函数,生成器函数中可以存在多个yield,一个next对一个yield的返回值,yield不会结束函数的调用,但return会结束函数的调用。
#举例运用: def func(): for i in range(1000000): yield i ret = func() i = 1000000 while i >= 0: print(next(ret)) i -= 1
-
如果再次调用yield就会接着上次的next.
def func(): for i in range(1000000): yield i ret = func() for i in range(5): print(next(ret)) for i in range(10): print(next(ret)) #0, 2,3,4,5,6,7,8,9,10,11,12,13,14
-
yield from(3.4版本以后):将数据变成一个迭代器返回
def func(): l1 = [1,2,3,4,] yield l1 print(next(func())) #[1, 2, 3, 4] def func(): l1 = [1,2,3,4,] yield from l1 #将这个列表变成了一个迭代器返回 print(next(func())) #1 print(nex(func())) #2
-
生成器函数可以直接用for循环:
def func(): l1 = [1,2,3] yield from l1 for i in func(): print(i) #1 2 3
-
-
列表推导式,生成器表达式:
-
列表推导式:用一行代码构建一个比较复杂有规律的列表。
l1 = [i for i in range(10)] #可将range换为可迭代对象。
-
列表推导式可分为两类。
-
循环模式:需遍历每一个元素。[变量(加工后的变量) for 变量 in iterable]
#例1:将10以内所有整数的平方写入列表: l1 = [i*i for i in range(11)] print(l1) #例2:100以内的所有奇数写入列表: l1 = [i for i in range(1,100,2)] print(l1) #例3:从python1到python10写入列表: l1 = [f'python{i}' for i in range(1,11)] print(l1)
-
筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]
#例1:将10以内能够被2整除的数写入列表 l1 = [i for i in range(11) if i%2==0] print(l1) #例2:过滤列表l1中小于3的字符串,将剩下的转换成大写。l1 = ['nonl','globals','as','in'] l1 = ['nonl','globals','as','in'] l2 = [i.upper() for i in l1 if len(i)>=3] print(l2) #例3:将num列表中含有两个0的字符串生成一个新列表。num = [['021','001','201'],['100','012','010']] l1 = [j for i in num for j in i if j.count('0') == 2] print(l1)
-
-
生成器表达式:与列表推导式的写法几乎一样,生成器也有循环模式和筛选模式,只是将[]变为()。但比列表推导式更节省空间。
l1 = (i for i in range(10)) print(l1) #<generator object <genexpr> at 0x000001BB028F8CC8> print(next(l1)) #0
l1 = (i for i in range(10)) for i in l1: #可直接用for循环,因为for循环本身就是将可迭代对象变为迭代器再循环。 print(i)
-
列表推导式
- 缺点:
- 只能构建计较复杂并且有规律的列表;
- 超过三层循环才能构建成功的,不建议使用列表推导式;
- 无法找查错误(debug模式)
- 缺点:
-
字典推导式
l1 = ['1','2','3'] l2 = ['一','二','三'] dic = {l1[i]:l2[i] for i in range(len(l1))}
-
集合推导式
set1 = {i for i in range(10)}
-
-
内置函数:
-
python提供了68个内置函数。
- 一级难点:abs() enumerate() filter() max() min() open() range() print() len() list() dict() str() float() reversed() set() sum() tuple() type() zip() dir()
- 二级难点:classmethod() delattr() getattr() issubclass() isinstance() object() property() setattr() staticmethod() super()
- 三级难点:all() any() bytes() callable() chr() complex() divmod() eval() exec() format() frozenset() globals() hash() help() id() input() int() locals() next() oct() ord() pow() repr() round()
-
eval():剥去字符串的外衣(引号),运算里面的代码,有返回值。工作时最好不用,容易中病毒。
s1 = '1+1' print(s1) #1+1 print(eval(s1),type(eval(s1))) #2 <class 'int'>
-
exec():与eval()几乎一样,但是它是处理代码流的。工作时最好不用,容易中病毒。
msg = """ for i in range(5): print(i)""" exec(msg) #0,1,2,3,4
-
hash:获取一个对象(可哈希对象:int,str,bool,tuple)的哈希值。
- 哈希值:加密算法之间需要哈希值,与哈希算法有关。
print(hash('12'))
-
help():打印/获取一个对象的使用方法。
print(help(str)) print(help(str.upper))
-
callable():判断一个对象是否可调用,真为True,假为False。
l1 = [1,2] def func(): pass print(callable(l1)) #False print(callable(func)) #True
剩余内置函数后续更新。
-