# 命名元组 from collections import namedtuple # typename: 定义这个元组的名称 # field_names: 这个元组元素的名称,可以有多种表达方式,如:‘name1 name2’ 或 ‘name1, name2’ 或 [‘name1’, ‘name2’] tup_name = namedtuple('tup_name', ['name', 'age']) # 创建一个命名元组的类叫 tup_name print(type(tup_name)) #类 a1 = tup_name('aa', age=22) # 用类 tup_name 创建对象 a1 传参赋值 print(isinstance(a1, tuple)) # 属于元组类型,内容定义好后不可修改,命名元组比字典更省内存 print(type(a1)) # 对象 print(a1) # tup_name(name='aa', age=22) print(a1[0]) # 可通过索引取值 print(a1.name) # 可通过k取值
# 列表推导式,可以用来快速生成一个有规律的列表 print([i for i in range(10)]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 列表推导式结合if条件过滤,先运行for循环部分再运行if条件过滤最后运行for之前的部分做数据处理添加到列表 print([i + 1 for i in range(10) if i % 2 == 0]) # [1, 3, 5, 7, 9] # 三目运算符是只要满足if条件就赋值给前面的i,否则就把else的值赋给i number = 99 num = number if number > 5 else 0 print(num) # 只要满足if num就是number的值,不满足就是0 # a if a>b else c if c>d else d 可以理解为 a if a>b else ( c if c>d else d ) 支持嵌套 # 列表推导式结合三目运算符条件过滤,先运行for循环部分再运行三目运算符条件过滤最后运行if之前的部分做数据处理添加到列表 # 在列表推导式中三目运算符只能用在for之前 print([i if i % 2 != 0 else 0 for i in range(10)]) # [0, 1, 0, 3, 0, 5, 0, 7, 0, 9] # 字典推导式,可以快速生成一个有规律的字典 li = ['a', 'b', 'c', 'd'] print({k: v for k, v in enumerate(li)}) # {0: 'a', 1: 'b', 2: 'c', 3: 'd'} name = ["张三", "李四", "王五", "李六"] # 保存名字列表 sign = ["白羊座", "双鱼座", "狮子座", "处女座"] # 保存星座列表 dict1 = {i: j for i, j in zip(name, sign)} # 字典推导式 print(dict1) # {'张三': '白羊座', '李四': '双鱼座', '王五': '狮子座', '李六': '处女座'} ssss = 'ss=11;ss22=22;aa=11;aa22=22;cc=11;cc22=22' print({k: v for k, v in [i.split('=') for i in ssss.split(';')]}) # {'ss': '11', 'ss22': '22', 'aa': '11', 'aa22': '22', 'cc': '11', 'cc22': '22'} # 字典推到式同样可以在for循环后面加if条件过滤,或者在for循环之前加三目运算符 print({i for i in range(5)}) # 集合推导式
同样也有元组推导式,但是这种是错误叫法,正确叫法是生成器表达式
迭代器对象
即实现了迭代器协议的对象
迭代器协议
1、对象实现了__iter__方法,那么这个对象就实现了迭代协议
2、定义了__next__方法
迭代器协议是由__iter__方法、__next__方法组成的。
Python中常见的数据类型,实现了迭代协议的有 字符串、列表、元组、集合、字典、range...
直白来说,能够使用for循环进行遍历的都叫可迭代对象,所有的迭代器都是可迭代对象
创建迭代器
使用内置函数iter(可迭代对象)即可创建一个迭代器对象
迭代器特性
1、可使用next()即可依次获取数据
2、获取完毕后再next()迭代报错
迭代器的作用
节约内存,提升程序的性能
li = [1, 2, 3] itor = iter(li) print(itor) #迭代器对象 print(next(itor)) # 1 print(next(itor)) # 2 print(next(itor)) # 3 print(next(itor)) # 报错 StopIteration # 也可使用for循环去遍历迭代器,但是由于迭代器内不存放数据,存放的是数据生成规则,迭代出一条数据以后就没有这个了 # print(next(itor)) 此时计算得到 1 # for i in itor: 遍历从2开始,结束即停止 # print(i)
生成器
是一种特殊的迭代器,具备迭代器所有的特性并有自身特有的特性,生成器内同样不存储数据,只保存生成数据的计算规则。
生成器定义方法
1、使用生成器表达式去定义生成器 如 res = ( i for i in range(100))
2、使用生成器函数去创建生成器
生成器函数:只要函数中定义了yield这个关键字,那么就是一个生成器函数,生成器函数不会直接执行,会返回一个生成器
# 生成器表达式 res_g = (i for i in range(3)) print(res_g) #at 0x000001A404A5B200> print(next(res_g)) print(next(res_g)) # print(next(res_g)) # print(next(res_g)) # 超出报错StopIteration # for j in res_g: # print(j) # 生成器函数 def func(): print('111111111111111') yield print('222222222222222') yield 1 print('333333333333333') fun = func() # 可以创建多个生成器,id不一样 print(fun) # at 0x000001EAE828C200> 生成器 # 当我们使用next去获取生成器中的数据(使用next对生成器进行迭代 *** 作) print(next(fun)) # 每次执行都会到yield处并把yield后面的值返回,没有值时返回None print(next(fun)) # 1 ,从上次执行到的位置继续执行到下一个yield并返回后面的值 # print(next(fun)) # 超出,后面没有yield时报异常StopIteration # for i in fun: # print(i) # 可以使用for循环,i值为每个yield后面返回的值 # 生成器和迭代器的区别,生成器比迭代器多的几个自身独有的特性 # 1、send()方法,类似next的进阶版,可以传参给函数内部yield之前的s, # 使用该方法之前必须先使用最少一次next启动生成器生成过一个数据 # 否则报错TypeError: can't send non-None value to a just-started generator # 2、close()方法,关闭该生成器,关闭后该生成器再次使用就报错StopIteration # 生成器函数每次调用都会生成一个新的生成器,只能生成新的去调用 # 3、throw()方法,在生成器内部上一次暂停的yield处主动引发一个指定异常类型,生成器内部可以使用try # 使用之前先使用最少一次next启动生成器生成过一个数据即可被正常捕获,否则直接抛出该异常终止运行且不能被捕获 def func1(): for i in range(10): s = yield i gen = func1() print(next(gen)) # 0 print(gen.send(666)) # 1 ,666传给s # print(gen.close()) # 关闭生成器 # print(next(gen)) # 关闭后再次调用报错StopIteration def func1_Send(): num = 1 for i in range(10): s = yield i * num num = s or num gen_send = func1_Send() print(next(gen_send)) # 0 print(gen_send.send(5)) # 5 , num=5 print(next(gen_send)) # 10 , num=5 print(gen_send.send(10)) # 30 , num=10 print(next(gen_send)) # 40 , num=10 def func2(): for i in range(10): try: s = yield i except TypeError: yield 'TypeError11' except ValueError: yield 'ValueError11' gen2 = func2() print(next(gen2)) print(gen2.throw(TypeError)) # TypeError11 返回值
def fun22(): name = yield for i in range(5): if type(name) != str: name = '127.0.0.1' name = yield 'http://' + name + '/user/login' gg = fun22() next(gg) res = gg.send('www.baidu.com') print(res) # http://www.baidu.com/user/login , www.baidu.com赋值给了第一个name,即上次暂停处 res1 = gg.send('www.sohu.com') print(res1) # http://www.sohu.com/user/login , www.sohu.com赋值给了第二个yield前的name,即上次暂停处 res2 = gg.send('www.sogou.com') print(res2) # http://www.sogou.com/user/login , www.sogou.com赋值给了第二个yield前的name,即上次暂停处
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)