个人学习总结笔记如有不足和错误欢迎指教谢谢
一、迭代器
1、迭代器可以记住被遍历地对象,被遍历得位置
2、迭代器会依次访问集合中的所有元素,并且不会倒退访问,当访问到最后一个元素时会结束
3、元祖、列表、字符串等都可以创建迭代器
iter() 、.__iter__()
使用这个命令创建迭代器
next()、.__next__()
使用这个命令调用迭代器中的元素
aa = 'abcde'
ab = aa.__iter__() # 把aa制作成迭代器 然后赋值给变量ab
print(ab.__next__()) # a
print(ab.__next__()) # b
print(ab.__next__()) # c
print(ab.__next__()) # d
print(ab.__next__()) # e
下面是iter() 、.__iter__()和next()、.__next__()的不同书写格式,他们的效果是一样的
aa = 'abcde'
ab = aa.__iter__() # 把aa制作成迭代器 然后赋值给变量ab
ac = iter(aa) # 把aa制作成迭代器 然后赋值给变量ab
print(next(ac)) # a
print(ab.__next__()) # a
但是如果在开始的例子中再多写一行,也就是多使用一次next
print(ab.__next__())
这个程序就会报错,因为迭代器已经循环完了,再也取不出元素了
报错内容如下
StopIteration
还可以设置循环多少次之后,触发这个报错
这整个过程就是一个for循环
for i in aa:
print(i)
for循环做了两件事
1、把要执行得参数变成可迭代对象,也就是把字符串aa变成了可迭代对象,使用.__iter__() #遵循迭代器协议 生成可迭代对象
2、执行next依次取出元素,使用.__next__()
并且for循环不会因为过多的使用next命令而导致程序报错,也就是for会自己判断可以迭代的次数
而且for循环 每次只取一个元素 加载到内存中,使用之后就会释放,所以for比较节省内存空间
二、生成器
1、使用了yield关键字的函数就是生成器,这个yield和return有些类似,只不过return之后函数的数据在内存中就被清除了。
2、当函数内遇到yield时,返回这个yield对应得值,并且函数内其他数据将被保存,以便下次调用取出时使用
def xunhuan():
yield 0
yield 1
yield 2
x = xunhuan()
print(next(x)) # 0
print(next(x)) # 1
print(next(x)) # 2
三、三元表达式
'abc' if n == 5 else '456'
如果 n 等于5 则返回 abc 如果n 不等于5 则返回 456
实例
n = 8
x = 'abc' if n == 5 else '456'
print(x) # 456
上面的命令和下面的命令效果时一样的
n = 8
if n == 5:
print('abc')
else:
print('456')
四、列表解析
这就是列表解析
l = ['%s本书' %i for i in range(10)] # 三元表达式
print(l)
上面的命令和下面的命令效果是相同放入
l = []
for i in range(10):
x = '%s本书'%i
l.append(x)
print(l) # ['0本书', '1本书', '2本书', '3本书', '4本书', '5本书', '6本书', '7本书', '8本书', '9本书']
这时候所有的 列表中的元素都存在内存中,这时候他们区别还不是很明显
观察一下下面两条命令
print(sum(i for i in range(10000000))) # 49999995000000
千万不要执行下面的命令
# 不要执行
l = []
for i in range(10000000):
l.append(i)
print(sum(l)) # 不要执行
他们输出的结果是相同的
但是第一条程序的列表并没有全部被写如内存而是 依次被带入sum函数中进行加工
第二条程序会把整个列表全部加载到内存中再使用sum函数进行加工
显然我们喜欢使用第一种解决方案
ps:使用列表解析我们的程序执行效率会变高