python迭代器(函数名的应用,新版格式化输出f)
-
内容大纲
- 函数名的运用
- 新特性:格式化输出
- 迭代器:
- 可迭代对象
- 获取对象的方法 dir()
- 判断一个对象是否是可迭代对象
- 小结
- 迭代器
- 迭代器的定义
- 判断一个对象是否是迭代器
- 迭代器的取值
- 可迭代对象如何转化成迭代器
- while循环模拟for循环机制
- 小结
- 可迭代对象与迭代器的对比
-
详细内容:
-
函数名的运用:
函数名的定义和变量的定义几乎一致,在变量的角度,函数名其实就是一个变量,具有变量的功能:可以赋值;但是作为函数名他也有特殊的功能就是加上()就会执行对应的函数,所以我们可以把函数名当做一个特殊的变量。
1:函数名指向的是函数的内存地址,函数名 + () 就可以执行此函数 a =1 a()#typeerror: 'int' object is not callable 不可调用 a = 1 b = 2 print(a + b)#3 a与b可以相加,与a,b这两个变量本身无关,与变量指向的对象有关。 def func(): print(666) func()#666 之所以func + () 可以执行,与func (函数名) 指向的内存地址有关。函数的内存地址()才是执行这个函数的关键 print(func,type(func))#<function func at 0x000001cb29a71e18> <class 'function'> 2:函数名就是变量(函数名可以赋值给其他变量) def func(): print(666) f = func #变量的赋值 f1 = f f2 = f1 f()#666 func()#666 f1()#666 f2()#666 def func(): print('in func') def func1(): print('in func1') func1 = func func1()#in func 3:函数名可以作为容器类数据类型的元素 def func1(): print('in func1') def func2(): print('in func2') def func3(): print('in fnc3') l1 = [func1,func2,func3] for i in l1: i() # # in func1 # # in func2 # # in fnc3 # #类比: a = 1 b = 2 c = 3 l1 = [a,b,c] print(l1)#[1, 2, 3] 4;函数名可以作为函数的参数 def func(a): print(a) print('in func') b = 3 func(b) # # 3 # # in func def func(): print('in func') def func1(x): x() print('in func1') func1(func) # # in func # # in func1 5:函数名可以作为函数的返回值 def func(): print('in func') def func1(x): # 传参相当于x = func print('in func1') return x ret = func1(func) ret() #相当于func() # ret, x, func1 都是指向的func1这个函数的内存地址 # # in func1 # # in func
-
新特性:格式化输出
[1]格式花输出 %s format name = '太白' age = 18 msg ='我叫%s,今年%s' %(name,age) msg1 = '我叫{},今年{}'.format(name,age) print(msg)#我叫太白,今年18 print(msg1)#我叫太白,今年18 [2]python3.6之后的新特性:格式化输出 f 或 f : name = '太白' age = 18 msg = f'我叫{name},今年{age}' print(msg)#我叫太白,今年18 (1)可以加任意表达式: dic = {'name':'alex','age':18} msg = f"我叫{dic['name']},今年{dic['age']}" print(msg)#我叫alex,今年18 count = 7 print(f'最终结果是:{count**2}')#最终结果是:49 name = 'barry' msg = f'我的名字是{name.upper()}' print(msg)#我的名字是barry l1 = ['太白金星', 18] msg = f'姓名:{l1[0]},年龄:{l1[1]}.' print(msg) # 姓名:太白金星,年龄:18. (2)结合函数写:可以用函数完成相应的功能,然后将返回值返回到字符串相应的位置 def _sum(a,b): return a + b msg = f'最终的结果是:{_sum(10,20)}' print(msg)#最终的结果是:30 (3)多行f: name = 'barry' age = 18 ajd = 'handsome' speaker = f'hi {name}.'\ f'you are {age} years old.'\ f'you are a {ajd} guy!' print(speaker) (4)其它: print(f"{{73}}") # {73} print(f"{{{73}}}") # {73} print(f"{{{{73}}}}") # {{73}} 注意: ! , : { } ;这些标点不能出现在{} 这里面。 print(f'{;12}') # 报错 # 所以使用lambda 表达式会出现一些问题。 # 解决方式:可将lambda嵌套在圆括号里面解决此问题。 x = 5 print(f'{(lambda x: x*2) (x)}') # 10
优点:
结构更加简化。
可以结合表达式,函数进行使用。
效率提升很多。
-
迭代器:
-
可迭代对象:
字面意思:对象?:python中一切皆对象。一个实实在在存在的值,对象。
可迭代?:更新迭代。重复的,循环的一个过程,更新迭代每次都有新的内容,
可迭代对象-->可以进行循环更新的一个实实在在值。
专业角度:可迭代对象--> 内部含有
'__iter__'
方法的对象,可迭代对象。目前学过的可迭代对象:str bytes list tuple dict set range 文件句柄
获取对象的所有方法并且以字符串的形式表现:dir() 会返回一个列表,这个列表中含有该对象的以字符串的形式所有方法名
-
判断一个对象是否是可迭代对象:
'__iter__'` in dir(对象) s1 = 'asdfghj' print(dir(s1)) print('__iter__' in dir(s1))#true l1 = [1,2,3] print(dir(l1)) print('__iter__' in dir(l1))#true b1 = b'wert' print(dir(b1)) print('__iter__' in dir(b1))#true print('__iter__' in dir(range(10)))#true
-
优缺点:
-
优点:
- 存储的数据直接能打印显示,比较直观。
- 拥有的方法比较多,操作方便。
-
缺点:
占用内存。
-
不能直接通过for循环进行取值,不能直接取值(索引,key除外)。
- 可迭代对象不能迭代取值(除去索引,key以外)
- for内部先将可迭代对象转化为迭代器,然后用next对迭代器取值。
-
迭代器
-
迭代器的定义
- 字面意思:更新迭代,器:工具:可更新迭代的工具。
- 专业角度:内部含有
'__iter__'
方法并且含有'__next__'
方法的对象就是迭代器。 - 迭代器是这样的对象:实现了无参数的__next__方法,返回序列中的下一个元素,如果没有元素了,那么抛出stopiteration异常.python中的迭代器还实现了__iter__方法,因此迭代器也可以迭代。 出自《流畅的python》
- 可以判断是否是迭代器:
'__iter__'
and'__next__'
在不在dir(对象)
-
判断一个对象是否是迭代器:
with open('文件1',encoding='utf-8',mode='w') as f1: print(('__iter__' in dir(f1)) and ('__next__' in dir(f1))) 目前学过的迭代器:文件句柄 s = 'asdff' print('__next__' in dir(s))# false
-
转化,取值 :
1.可迭代对象转化为迭代器:对可迭代对象操作,形成一个迭代器。str还是str,list还是list
-
2.对迭代器取值:一个next() 取一个值,少一个next()可以,多一个就会报错.
可迭代对象是不可以一直迭代取值的(除去用索引,切片以及key),但是转化成迭代器就可以了,迭代器是利用__next__()进行取值
迭代器利用next取值:一个next取对应的一个值,如果迭代器里面的值取完了,还要next,那么就报stopiteration的错误。
s1 = 'asdf' obj = iter(s1) #转化为迭代器 print(obj)#<str_iterator object at 0x000002216db77828> print(next(obj))#a print(next(obj))#s print(next(obj))#d print(next(obj))#f s1 = 'asdf' obj = s1.__iter__() #转化为迭代器 print(obj)#<str_iterator object at 0x000001fe307877f0> print(obj.__next__())#a print(obj.__next__())#s print(obj.__next__())#d print(obj.__next__())#f l1 = [11,22,33,44,55,66] obj = l1.__iter__() print(obj) print(obj.__next__()) #对迭代器取值 print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) print(obj.__next__()) l1 = [11,22,33,44,55,66] obj = iter(l1) print(obj) print(next(obj)) #对迭代器取 print(next(obj)) print(next(obj)) print(next(obj)) print(next(obj)) print(next(obj)) # l1 = [11,22,33,44,55,66,77,88,99,1010,1111,1212] count = 0 for i in l1: if count == 4: break else: print(i) count += 1 # # 11 # # 22 # # 33 # # 44 count = 0 for i in l1: if count == 6: break else: print(i) count += 1 # # 11 # # 22 # # 33 # # 44 # # 55 # # 66 #迭代器永远会记住取值的位置 l1 = [11,22,33,44,55,66,77,88,99,1010,1111,1212] obj = iter(l1) for i in range(4): print(next(obj)) # # 11 # # 22 # # 33 # # 44 for i in range(6): print(next(obj)) # # 55 # # 66 # # 77 # # 88 # # 99 # # 1010 l1 = [11,22,33,44,55,66,77,88,99,1010,1111,1212] for i in l1: print(i)
-
while循环模拟for循环机制【面试经常考】
将可迭代对象转换成迭代器,然后利用next进行取值,最后利用异常处理处理stopiteration抛出的异常 l1 = [11,22,33,44,55,66,77,88,99,1111,1133,15652] # 将可迭代对象转化成迭代器。 obj = iter(l1) while 1: try: print(next(obj)) except stopiteration: break
-
小结:
- 字面意思:更新迭代,器:工具:可更新迭代的工具。
- 专业角度:内部含有
'__iter__'
方法并且含有'__next__'
方法的对象就是迭代器。 - 优点:
- 节省内存。
- 惰性机制, next一次,取一个值,绝不过多取值。
- 缺点:
- 速度慢。
- 不走回头路。 取值时不走回头路,只能一直向下取值
-
可迭代对象与迭代器的对比:
- 可迭代对象:可迭代对象是一个操作方法比较多,比较直观,存储数据相对少(几百万个对象,8g内存是可以承受的)的一个数据集。
- 应用:当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
- 迭代器:迭代器是非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
- 应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。
-
-
-
总结
- 格式化输出 ***
- 函数名的应用。***
- 对比:迭代器是什么? 迭代器的优缺点。可迭代对象转化成迭代器。next取值. ***
上一篇: 盘点历史上被误会的诗句,“执子之手,与子偕老”写的不是爱情
下一篇: 接口测试(四)总结及小技巧笔记