在python中有三种方式来构建生成器:
1. 通过生成器推导式 g = (lambda x: x*i for i in rang(4))
2. 通过生成器函数 yield 语句(相当于...return + hold...)RH (下次取值先找 hold点)
yield 生成值;
生成器函数+():只是代表一个生成器对象,并不是函数执行;
可理解为惰性机制,在不执行函数的前提下,获得(返回)该生成器对象。
3. python内置函数或者模块提供(其实2,3两种本质上差不多,都是通过函数的形式生成,
只不过2是自己写的生成器函数,3是python提供的生成器函数而已)
def func(): print("111") yield 222 gener = func() # ()这个时候函数不会执行,()而是获取到生成器 ret = gener.__next__() # 这个时候函数才会执行, 也可以用 next(gener) print(ret) 运行结果: 111 222
#!/usr/bin/env python # -*- coding:utf-8 -*- def gen(name): print(f'{name} ready to eat') n = 100 while 1: food = yield n print(food) print(f'{name} start to eat {food}') n = n + 1 dog = gen('alex') # 第一次必须用next让指针停留在第一个yield后面 或者 send(None) ret = dog.send('骨头') # 与__next__一样,可以获取到yield的值 # 还可以在本次执行__next__的过程中传入一个值,供生成器使用 print(ret)
#!/usr/bin/env python # -*- coding:utf-8 -*- def gen_demo(): value = yield 1 yield value gen = gen_demo() print(next(gen)) print(gen.send("I am Value!"))
其实,send和next的执行很像,只是send可以和生成器互动,传入一个值。
列表推导式分为两种模式:
1.循环模式:[变量(加工的变量) for 变量 in iterable]
2.循环筛选模式: [变量(加工的变量) for 变量 in iterable if 条件]
1 li1 = [i for i in range(10)] 2 li2 = [f'神舟{i}号' for i in range(1, 9)] 3 li3 = [i for i in range(30) if i % 3 == 0]
生成器表达式和列表推导式的语法上一模一样,只是把 [ ] 换成 ( ) 就行了。
生成器推导式和列表推导式的区别:
1.列表推导式比较耗内存,所有数据一次性加载到内存。而.生成器表达式遵循迭代器协议,逐个产生元素。
2.得到的值不一样,列表推导式得到的是一个列表.生成器表达式获取的是一个生成器
3.列表推导式一目了然,生成器表达式只是一个内存地址。
# 字典推导式 dic = {lst1[i]:lst2[i] for i in range(len(lst1))}
# 集合推导式 s = {abs(i) for i in lst}
eval('2 + 2') # 4 s = ''' for i in [1,2,3]: print(i) ''' exec(s)
dict1 = {True: 'alex', 1: 'wusir'} print(dict1[True]) # wusir print(hash(True), hash(1)) # 1 1
print(int()) print(int('12')) print(int(3.9)) # 并没有四舍五入 print(int('0100', base=2)) 运行结果: 0 12 3 4
float() 用于将整数和字符串转换成浮点数。
complex() 用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不能传入第二个参数。
print(float(3)) print(complex(1)) print(complex(1, 2)) print(complex('3+4j')) print(complex('12')) 运行结果: 3.0 (1+0j) (1+2j) (3+4j) (12+0j)
print(bin(-10)) print(oct(250)) print(hex(250)) 运行结果: -0b1010 0o372 0xfa
print(divmod(7, 3)) print(round(7 / 3)) # 默认不保留小数 print(round(7 / 3, 2)) print(round(2.333501, 3)) # 四舍五入 print(pow(2, 3)) print(pow(2, 3, 3)) 运行结果: (2, 1) 2 2.33 2.334 8 2
bytes() 编码(编成 B码)。 str() 解释 B码。
s1 = '你好' # 字符串'你好',两个字符'你'、'好' bs1 = s1.encode('utf-8') # 编码=编译成字节码:把字符串中对字符编译成指定字节码 'utf-8'码 print(bs1) # b'xe4xbdxa0xe5xa5xbd' s1b = bs1.decode('utf-8') # 解码=解释字节码:把特定字节码按照指定方式解释出来,解释成字符。(方式要一致才可) print(s1b) # 你好 bs2 = bytes(s1, encoding='utf-8') # 编码 print(bs2) # b'xe4xbdxa0xe5xa5xbd' bs3 = bytes(s1, encoding='gbk') print(bs3) # b'xc4xe3xbaxc3' print(bs3.decode('gbk')) # 你好 # 可用str()来进行解码操作,解释字节码=用指定方式把特定字节码转化成字符(串)。 s2 = str(bs2, encoding='utf-8') print(s2) # 你好 s3 = str(bs3, encoding='gbk') print(s3) # 你好
ord() 输入字符找该字符Unicode编码的位置(万国码)。
chr() 输入Unicode位置数字找出其对应的字符。
print(ord('A')) # 65 print(ord('中')) # 20013 print(chr(97)) # a print(chr(20013)) # 中
repr() 返回一个对象的string形式(原形毕露)。
dict1 = {'a': 1, 'b': 2} str1 = "abc哟!" str2 = repr(dict1) str3 = repr(str1) print(str2, type(str2)) print(str3, type(str3)) 运行结果: {'a': 1, 'b': 2} <class 'str'> 'abc哟!' <class 'str'>
list1 = ['a', 'b', 'c'] for i in enumerate(list1): print(i) for i, j in enumerate(list1): print(i, j) for i, j in enumerate(list1, 10): print(i, j) 运行结果: (0, 'a') (1, 'b') (2, 'c') 0 a 1 b 2 c 10 a 11 b 12 c
''' 源码分析 def print(self, *args, sep=' ', end=' ', file=None): """ print(value, ..., sep=' ', end=' ', file=sys.stdout, flush=False) file: 默认是输出到屏幕,如果设置为文件句柄,输出到文件 sep: 打印多个值之间的分隔符,默认为空格 end: 每一次打印的结尾,默认为换行符 flush: 立即把内容输出到流文件,不作缓存 """ ''' print(111,222,333,sep='*') # 111*222*333 print(111,end='') print(222) # 两行的结果 111222 f = open('log','w',encoding='utf-8') print('重要学习资料...',file=f,flush=True) # 运行结果:屏幕无输出,log文件里写入了内容:'重要学习资料...'
list() 将一个可迭代对象转换成列表
tuple() 将一个可迭代对象转换成元组
dict() 通过相应的方式创建字典。
l1 = list('abcd') tu1 = tuple('abcd') print(l1, tu1) 运行结果: ['a', 'b', 'c', 'd'] ('a', 'b', 'c', 'd')
abs() 求绝对值
sum() 求和
print(sum([1, 2, 3])) print(sum((1, 2, 3), 100)) 运行结果: 6 106
min() 求最小值
max() 求最大值
print(min(-1, 0, 1)) print(min([1, 2, 3])) # 返回此序列的最小值 print(min((-1, 2, 5), key=abs)) # 加key是可以加函数名,就是加比较法则。 # 就是将需要做比较的各元素,按照key所代表的函数法则进行最小值比较,最终仍旧返回对应的原始元素。 #(即将各元素传参给法则函数,对返回值进行最小值比较)。 print(min(-2, -1, 2, 5, key=lambda x: abs(x))) # 可以设置多个参数比较大小。 dic = {'a': 1, 'b': 2, 'c': 3} print(min(dic, key=lambda x: dic[x])) # x为dic的键,函数法则就是键对应对值做最小值比较,最终返回对应对原始键。 运行结果: -2 1 -1 -1 a
reversed() 翻转。若将一个序列翻转, 返回翻转序列的迭代器;序列即列表。
l1 = reversed('你好') l2 = reversed((1, 2, 3, 4)) l3 = reversed([1, 2, 3, 4]) print(l1, type(l1)) print(l2, type(l2)) print(l3, type(l3)) print(list(l1), list(l2), list(l3)) 运行结果: <reversed object at 0x0000000002193408> <class 'reversed'> <reversed object at 0x0000000002193448> <class 'reversed'> <list_reverseiterator object at 0x0000000002193488> <class 'list_reverseiterator'> ['好', '你'] [4, 3, 2, 1] [4, 3, 2, 1]
sorted() 排序,可以通过key加函数制定排序规则
语法: sorted(iterable,key=None,reverse=False) iterable : 可迭代对象 key: 排序规则函数,sorted会将可迭代对象中的所有元素根据排序规则进行排序,(即将所有元素都传递给排序规则函数,按照运算的结果进行排序), 经过规则排序后,sorted最终返回对应的原始元素的排序。 reverse :是否是倒序,True 倒序 False 正序 lst = [1,3,2,5,4] lst2 = sorted(lst) print(lst) #原列表不会改变 print(lst2) #返回的新列表是经过排序的 lst3 = sorted(lst,reverse=True) print(lst3) #倒序 结果: [1, 3, 2, 5, 4] [1, 2, 3, 4, 5] [5, 4, 3, 2, 1] 字典使用sorted排序 dic = {1:'a',3:'c',2:'b'} print(sorted(dic)) # 字典排序返回的就是键的排序 结果: [1,2,3] 和函数组合使用 # 定义一个列表,然后根据一元素的长度排序 lst = ['天龙八部','西游记','红楼梦','三国演义'] # 计算字符串的长度 def func(s): return len(s) print(sorted(lst,key=func)) # 结果: # ['西游记', '红楼梦', '天龙八部', '三国演义'] 和lambda组合使用 lst = ['天龙八部','西游记','红楼梦','三国演义'] print(sorted(lst,key=lambda s:len(s))) 结果: ['西游记', '红楼梦', '天龙八部', '三国演义'] lst = [{'id':1,'name':'alex','age':18}, {'id':2,'name':'wusir','age':17}, {'id':3,'name':'taibai','age':16},] # 按照年龄对学生信息进行排序 print(sorted(lst,key=lambda e:e['age'])) 结果: [{'id': 3, 'name': 'taibai', 'age': 16}, {'id': 2, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'alex', 'age': 18}]
zip() 拉链方法。多个可迭代对象作为参数,功能:将多个对象中的元素按照索引对应拉在一起,组成元组,每个元组里都有一个这些可迭代对象的元素;返回一个迭代器。
若各个可迭代对象的元素个数不一致,则按照个数最少的返回。
lst1 = [1, 2, 3] lst2 = ['a', 'b', 'c', 'd'] lst3 = ('你', '我', '她', '他', '它') print(zip(lst1, lst2, lst3)) for i in zip(lst1, lst2, lst3): print(i) 运行结果: <zip object at 0x00000000021C3648> (1, 'a', '你') (2, 'b', '我') (3, 'c', '她')
语法: filter(function,iterable) function: 用来筛选的函数,在filter中会自动的把iterable中的元素传递给function,然后根据function返回的True或者False来判断是否保留此项数据 iterable:可迭代对象 lst = [{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}, {'id': 1, 'name': 'taibai', 'age': 16}, ] ls = filter(lambda d: d['age'] > 16, lst) print(ls, type(ls)) print(list(ls)) 运行结果: <filter object at 0x00000000021C3948> <class 'filter'> [{'id': 1, 'name': 'alex', 'age': 18}, {'id': 1, 'name': 'wusir', 'age': 17}]
映射函数 语法: map(function,iterable) 功能:对可迭代对象中的每一个元素进映射,分别去执行function,执行结果组成一个迭代器。 计算列表中每个元素的平方,返回新列表 lst = [1,2,3,4,5] def func(s): return s*s mp = map(func,lst) print(mp) print(list(mp)) 结果: <map object at 0x00000000023E34C8> [1, 4, 9, 16, 25] 改写成lambda lst = [1,2,3,4,5] print(list(map(lambda s:s*s,lst))) 计算两个列表中相同位置的数据的和 lst1 = [1, 2, 3, 4, 5] lst2 = [2, 4, 6, 8, 10] print(list(map(lambda x, y: x+y, lst1, lst2))) 结果: [3, 6, 9, 12, 15]
reduce() 递减函数
from functools import reduce def func(x,y): return x + y # reduce 的使用方式: # reduce(函数名, 序列) # 这两个参数必须都要有,缺一个不行 ret = reduce(func,[3,4,5,6,7]) print(ret) # 结果 25 reduce的功能:先把序列中的前俩个元素取出计算出一个值然后临时保存着,接下来用这个临时保存的值和序列中第三个元素进行计算, 求出一个新的值将前面的临时值覆盖掉,然后在用这个新的临时值和列表中第四个元素计算,依次类推...最后reduce返回一个最终值。 注意:我们放进去的序列没有更改 以上这个例子我们使用sum就可以完全的实现了.我现在有[1,2,3,4]想让列表中的数变成1234,就要用到reduce了. 普通函数版 from functools import reduce def func(x,y): return x * 10 + y # 第一次的时候 x是1 y是2 x乘以10就是10,然后加上y也就是2最终结果是12然后临时存储起来了 # 第二次的时候x是临时存储的值12 x乘以10就是 120 然后加上y也就是3最终结果是123临时存储起来了 # 第三次的时候x是临时存储的值123 x乘以10就是 1230 然后加上y也就是4最终结果是1234然后返回了 ret = reduce(func,[1,2,3,4]) print(ret) 结果: 1234 匿名函数版 l = reduce(lambda x,y:x*10+y,[1,2,3,4]) print(l) 在Python2.x版本中recude是直接 import就可以的, Python3.x版本中需要从functools这个包中导入 龟叔本打算将 lambda 和 reduce 都从全局名字空间都移除, 舆论说龟叔不喜欢lambda 和 reduce 最后lambda没删除是因为和一个人写信写了好多封,进行交流然后把lambda保住了.
参考资料:https://www.processon.com/view/link/5b4ee15be4b0edb750de96ac