迭代器
-
-
global nonlocal
-
函数名的运用
-
新特性:格式化输出
-
迭代器:
-
可迭代对象
-
获取对象的方法
-
判断一个对象是否是可迭代对象
-
小结
-
迭代器
-
迭代器的定义
-
判断一个对象是否是迭代器
-
迭代器的取值
-
可迭代对象如何转化成迭代器
-
while循环模拟for循环机制
-
小结
-
可迭代对象与迭代器的对比
-
-
-
昨日内容回顾以及作业讲解
-
函数的参数:
-
实参角度:位置参数,关键字参数,混合参数。
-
形参角度:位置参数,默认参数,仅限关键字参数,万能参数。
-
形参角度参数顺序:位置参数,*args, 默认参数,仅限关键字参数,**kwargs.
-
-
*的魔性用法:
-
函数的定义时:代表聚合。
-
函数的调用时:代表打散。
-
-
python中存在三个空间:
-
内置名称空间:存储的内置函数:print,input.......
-
全局名称空间:py文件,存放的是py文件(除去函数,类内部的)的变量,函数名与函数的内存地址的关系。
-
局部名称空间:存放的函数内部的变量与值的对应关系。
-
-
加载顺序:内置名称空间,全局名称空间, 局部名称空间(执行函数时)。
-
取值顺序:就近原则。LEGB.
-
局部作用域只能引用全局变量,不能修改。
name = 'alex'
def func():
name = name + 'sb'
-
-
作用域:
-
全局作用域:内置名称空间 + 全局名称空间。
-
局部作用域:局部名称空间。
-
-
函数的嵌套
-
globals() locals()
-
-
今日内容
-
global nonlocal
-
补充:
默认参数的陷阱
1 # 默认参数的陷阱: 2 # def func(name,sex='男'): 3 # print(name) 4 # print(sex) 5 # func('alex') 6 7 # 陷阱只针对于默认参数是可变的数据类型: 8 # def func(name,alist=[]): 9 # alist.append(name) 10 # return alist 11 # 12 # ret1 = func('alex') 13 # print(ret1,id(ret1)) # ['alex'] 14 # ret2 = func('太白金星') 15 # print(ret2,id(ret2)) # ['太白金星'] 16 17 # 如果你的默认参数指向的是可变的数据类型,那么你无论调用多少次这个默认参数,都是同一个。 18 19 # def func(a, list=[]): 20 # list.append(a) 21 # return list 22 # print(func(10,)) # [10,] 23 # print(func(20,[])) # [20,] 24 # print(func(100,)) # [10,100] 25 # l1 = [] 26 # l1.append(10) 27 # print(l1) 28 # l2 = [] 29 # l2.append(20) 30 # print(l2) 31 # l1.append(100) 32 # print(l1) 33 # 34 # def func(a, list= []): 35 # list.append(a) 36 # return list 37 # ret1 = func(10,) # ret = [10,] 38 # ret2 = func(20,[]) # [20,] 39 # ret3 = func(100,) # ret3 = [10,100] 40 # print(ret1) # [10,] [10,100] 41 # print(ret2) # 20,] [20,] 42 # print(ret3) # [10,100] [10,100] 43
局部作用域的坑:
1 # 默认参数的陷阱: 2 # def func(name,sex='男'): 3 # print(name) 4 # print(sex) 5 # func('alex') 6 7 # 陷阱只针对于默认参数是可变的数据类型: 8 # def func(name,alist=[]): 9 # alist.append(name) 10 # return alist 11 # 12 # ret1 = func('alex') 13 # print(ret1,id(ret1)) # ['alex'] 14 # ret2 = func('太白金星') 15 # print(ret2,id(ret2)) # ['太白金星'] 16 17 # 如果你的默认参数指向的是可变的数据类型,那么你无论调用多少次这个默认参数,都是同一个。 18 19 # def func(a, list=[]): 20 # list.append(a) 21 # return list 22 # print(func(10,)) # [10,] 23 # print(func(20,[])) # [20,] 24 # print(func(100,)) # [10,100] 25 # l1 = [] 26 # l1.append(10) 27 # print(l1) 28 # l2 = [] 29 # l2.append(20) 30 # print(l2) 31 # l1.append(100) 32 # print(l1) 33 # 34 # def func(a, list= []): 35 # list.append(a) 36 # return list 37 # ret1 = func(10,) # ret = [10,] 38 # ret2 = func(20,[]) # [20,] 39 # ret3 = func(100,) # ret3 = [10,100] 40 # print(ret1) # [10,] [10,100] 41 # print(ret2) # 20,] [20,] 42 # print(ret3) # [10,100] [10,100] 43
global nonlocal
1 global 2 1, 在局部作用域声明一个全局变量。 3 name = 'alex' 4 5 def func(): 6 global name 7 name = '太白金星' 8 # print(name) 9 func() 10 print(name) 11 12 13 def func(): 14 global name 15 name = '太白金星' 16 # print(name) 17 print(globals()) 18 func() 19 # print(name) 20 print(globals()) 21 22 2. 修改一个全局变量 23 count = 1 24 def func(): 25 # print(count) 26 global count 27 count += 1 28 print(count) 29 func() 30 print(count) 31 32 33 nonlocal 34 35 1. 不能够操作全局变量。 36 count = 1 37 def func(): 38 nonlocal count 39 count += 1 40 func() 41 2. 局部作用域:内层函数对外层函数的局部变量进行修改。 42 43 def wrapper(): 44 count = 1 45 def inner(): 46 nonlocal count 47 count += 1 48 print(count) 49 inner() 50 print(count) 51 wrapper()
-
-
函数名的运用
1 # def func(): 2 # print(666) 3 # 4 # # func() 5 # # 1. 函数名指向的是函数的内存地址。 6 # # 函数名 + ()就可以执行次函数。 7 # # a = 1 8 # # a() 9 # # func() 10 # # a = {'name': 'alex'} 11 # # b = {'age' : 18} 12 # # a = 1 13 # # b = 2 14 # # print(a + b) 15 # print(func,type(func)) # <function func at 0x000001BA864E1D08> 16 # func() 17 18 # 2, 函数名就是变量。 19 # def func(): 20 # print(666) 21 22 # a = 2 23 # b = a 24 # c = b 25 # print(c) 26 # f = func 27 # f1 = f 28 # f2 = f1 29 # f() 30 # func() 31 # f1() 32 # f2() 33 # 34 # def func(): 35 # print('in func') 36 # 37 # def func1(): 38 # print('in func1') 39 # 40 # func1 = func 41 # func1() 42 # a = 1 43 # b = 2 44 # a = b 45 # print(a) 46 47 # 3. 函数名可以作为容器类数据类型的元素 48 49 # def func1(): 50 # print('in func1') 51 # 52 # def func2(): 53 # print('in func2') 54 # 55 # def func3(): 56 # print('in func3') 57 # # a = 1 58 # # b = 2 59 # # c = 3 60 # # l1 = [a,b,c] 61 # # print(l1) 62 # l1 = [func1,func2,func3] 63 # for i in l1: 64 # i() 65 66 # 4. 函数名可以作为函数的参数 67 68 # def func(a): 69 # print(a) 70 # print('in func') 71 # b = 3 72 # func(b) 73 # print(func) 74 75 # def func(): 76 # print('in func') 77 # 78 # def func1(x): 79 # x() # func() 80 # print('in func1') 81 # 82 # func1(func) 83 84 # 5. 函数名可以作为函数的返回值 85 def func(): 86 print('in func') 87 88 def func1(x): # x = func 89 print('in func1') 90 return x 91 92 ret = func1(func) # func 93 ret() # func() 94
-
新特性:格式化输出
1 # %s format 2 # name = '太白' 3 # age = 18 4 # msg = '我叫%s,今年%s' %(name,age) 5 # msg1 = '我叫{},今年{}'.format(name,age) 6 7 # 新特性:格式化输出 8 # name = '太白' 9 # age = 18 10 # msg = f'我叫{name},今年{age}' 11 # print(msg) 12 13 # 可以加表达式 14 # dic = {'name':'alex','age': 73} 15 # msg = f'我叫{dic["name"]},今年{dic["age"]}' 16 # print(msg) 17 18 # count = 7 19 # print(f'最终结果:{count**2}') 20 # name = 'barry' 21 # msg = f'我的名字是{name.upper()}' 22 # print(msg) 23 24 # 结合函数写: 25 def _sum(a,b): 26 return a + b 27 28 msg = f'最终的结果是:{_sum(10,20)}' 29 print(msg) 30 # ! , : { } ;这些标点不能出现在{} 这里面。
优点:
-
结构更加简化。
-
可以结合表达式,函数进行使用。
-
效率提升很多。
-
-
迭代器:
-
可迭代对象
字面意思:对象?python中一切皆对象。一个实实在在存在的值,对象。
可迭代?:更新迭代。重复的,循环的一个过程,更新迭代每次都有新的内容,
可以进行循环更新的一个实实在在值。
专业角度:可迭代对象? 内部含有
'__iter__'
方法的对象,可迭代对象。目前学过的可迭代对象?str list tuple dict set range 文件句柄
-
获取对象的所有方法并且以字符串的形式表现:dir()
-
判断一个对象是否是可迭代对象
1 s1 = 'fjdskl' 2 # l1 = [1,2,3] 3 # # print(dir(s1)) 4 # print(dir((l1))) 5 # print('__iter__' in dir(s1)) 6 # print('__iter__' in dir(range(10)))
-
小结
-
字面意思:可以进行循环更新的一个实实在在值。
-
专业角度: 内部含有
'__iter__'
方法的对象,可迭代对象。 -
判断一个对象是不是可迭代对象:
'__iter__'
in dir(对象) -
str list tuple dict set range
-
优点:
-
存储的数据直接能显示,比较直观。
-
拥有的方法比较多,操作方便。
-
-
缺点:
-
占用内存。
-
不能直接通过for循环,不能直接取值(索引,key)。
-
-
-
迭代器
-
迭代器的定义
-
字面意思:更新迭代,器:工具:可更新迭代的工具。
-
专业角度:内部含有
'__iter__'
方法并且含有'__next__'
方法的对象就是迭代器。 -
可以判断是否是迭代器:
'__iter__'
and'__next__'
在不在dir(对象)
-
-
判断一个对象是否是迭代器
1 with open('文件1',encoding='utf-8',mode='w') as f1: 2 print(('__iter__' in dir(f1)) and ('__next__' in dir(f1))) 3
-
迭代器的取值
1 s1 = 'fjdag' 2 obj = iter(s1) # s1.__iter__() 3 # print(obj) 4 # print(next(obj)) # print(obj.__next__()) 5 # print(next(obj)) # print(obj.__next__()) 6 # print(next(obj)) # print(obj.__next__()) 7 # print(next(obj)) # print(obj.__next__()) 8 # print(next(obj)) # print(obj.__next__()) 9 # print(next(obj)) # print(obj.__next__()) 10 11 # l1 = [11,22,33,44,55,66] 12 # obj = iter(l1) 13 # print(next(obj)) 14 # print(next(obj)) 15 # print(next(obj)) 16 # print(next(obj)) 17 # print(next(obj)) 18 # print(next(obj))
-
可迭代对象如何转化成迭代器
1 iter([1,2,3])
-
while循环模拟for循环机制
1 l1 = [11,22,33,44,55,66,77,88,99,1111,1133,15652] 2 # 将可迭代对象转化成迭代器。 3 obj = iter(l1) 4 while 1: 5 try: 6 print(next(obj)) 7 except StopIteration: 8 break
-
小结
-
字面意思:更新迭代,器:工具:可更新迭代的工具。
-
专业角度:内部含有
'__iter__'
方法并且含有'__next__'
方法的对象就是迭代器。 -
优点:
-
节省内存。
-
惰性机制,next一次,取一个值。
-
-
缺点:
-
速度慢。
-
不走回头路。
-
-
-
可迭代对象与迭代器的对比
-
可迭代对象是一个操作方法比较多,比较直观,存储数据相对少(几百万个对象,8G内存是可以承受的)的一个数据集。
-
当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
-
是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
-
当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。
-
-
-
-
今日总结
-
默认参数的坑,作用域的坑 ***
-
格式化输出 ***
-
函数名的应用。***
-
对比:迭代器是什么? 迭代器的优缺点。可迭代对象转化成迭代器。next取值. ***
-
-
明日内容