1.迭代器
迭代取值的工具
s = 'hello' n = 0 while n < len(s): print(s[n]) # h e l l o n += 1
# 每一次迭代都是基于上一次的结果而来的
能够迭代取值的数据类型:字符串、列表、元组、集合、字典
可迭代对象:只有内置有__iter__方法的都叫可迭代对象,可迭代对象执行内置的__iter__方法得到的就是该对象的迭代器对象
可迭代对象有 str list tuple dict set,文本对象
迭代器对象:内置__iter__方法,内置__next__方法,文件对象本身就是迭代器对象
ps:迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象。
l = [1,2,3,4,5,6] iter_1 = l.__iter__() # 生成一个迭代器对象 print(iter_1.__next__()) # 1 如果取完了,会报错
迭代器的对象的取值,必须用__next__
异常处理
l = [1,2,3,4,5,6] iter_1 = l.__iter__() while True: try: print(iter_1.__next__()) except StopIteration: # 用来接收没有值可取时的报错, break
迭代器的特点:只能往后依次取值,不能后退。
__iter__()等价于iter()
for 循环内部本质:
1.将 in 后面的对象调用__iter__转换成迭代器对象
2.调用__next__迭代处理
3.内部有异常捕获StopIteration,当__next__报这个错的时候自动结束循环。
迭代取值:
优点:不依赖索引取值,内存中只占一份空间,不会导致内存溢出。
缺点:不能获取指定的元素,取完之后,会报StopIteration错
2.生成器
用户自定义的迭代器
def func(): print('first') yield 9 # 函数内部有yield关键字,加括号执行函数的时候不会触发函数体的运行 print('second') yield 8 g = func() # 生成器初始化,将函数编程迭代器print(g.__next__()) #yield后面跟的值是调用迭代器__next__方法能够得到的值 print(g.__next__()) #yield可以返回一个值,也可以返回多个值,多个值以元组的形式返回
def my_range(start,end,step): while start < end: yield start start += step for j in my_range(1,8,2): print(j)
def dog(name): print('%s'%name) # egon while True: food = yield # yield支持外界传参 print('%s吃%s'%(name,food)) # egon吃饺子 g = dog('egon') # 函数体内有yield关键字,调用该函数不会执行函数体代码,而是将其变成一个迭代器 g.__next__() g.send('饺子')
yield 提供了一种自定义生成器的方法,会将函数的运行状态暂停住,然后返回值
与return的异同点
相同点:都可以返回值,并且都可以返回多个
不同点:yield可以返回多个值,而return只能返回一次函数立即结束,yield可以接受外部传入的值
res = [i for i in range(1,10) if i != 4] # 生成器表达式 print(res)
生成器不执行任何一行代码,必须通过__next__触发代码的运行
add(n,i): return n+i # n = 10,i = 0 n = 10,i = 10 def test(): for i in range(4): yield i g=test() for n in [1,10]: g=(add(n,i) for i in g) # 第一次for循环g=(add(n,i) for i in test()) # 第二次for循环g=(add(n,i) for i in (add(n,i) for i in test())) print(n) res=list(g) # res=[20,21,22,23
常用内置方法
print(abs(-11.11)) # 求绝对值
l = [0,1,0]
print(all(l)) # 只要有一个为False就返回False
print(any(l)) # 只要有一个位True就返回True
def index():
username = '我是局部名称空间里面的username'
print(locals()) # 当前语句在哪个位置 就会返回哪个位置所存储的所有的名字
print(globals()) # 无论在哪 查看的都是全局名称空间
index()
print(bin(10)) # 十转二
print(oct(10)) # 十转八
print(hex(10)) # 十转十六
print(int('0b1010',2)) # 二转十
print(int('0o1010',8)) # 八转十
print(int('0x1010',16)) # 十六转十
print(bool(1)) #True
print(bool(0)) # False
s = 'hello'
print(s.encode('utf-8')) # b'hello'
print(bytes(s,encoding='utf-8')) # b'hello'
def index():
passprint(callable(index)) #True
print(chr(97)) # 将数字转换成ascii码表对应的字符
print(ord('z')) # 将字符按照ascii表转成对应的数字
A-Z-->65-90 a-z-->97-122
l = [1,2,3]
print(dir(l)) # dir获取当前对象名称空间里面的名字
total_num,more = divmod(900,11)
if more:
total_num += 1
print('总页数:',total_num) # 总页数: 82
l = ['a','b']
for i,j in enumerate(l,0):
print(i,j) # 0 a <class 'int'> <class 'str'>
s = """
print('hello baby~')
"""
eval(s) # hello baby~
s = """
print('hello baby~')
x = 1
y = 2
print(x + y)
"""
exec(s) # hello baby~ 3
# eval不支持逻辑代码,只支持简单的python代
# format 三种玩法
# {}占位
# {index} 索引
# {name} 指名道姓
def login():
"""
一起嗨皮
:return:
"""
# print(help(login))
# isinstance 后面统一改方法判断对象是否属于某个数据类型
n = 1
print(type(n))
print(isinstance(n,list)) # 判断对象是否属于某个数据类型
print(pow(2,4)) # 16 2**4
print(round(1.4)) # 1 比较大小
面向过程编程
好处:将复杂的问题流程化,从而简单化
坏处:可扩性差 ,一旦修改,整体都会受影响