迭代器
可迭代对象
python中一切皆对象
凡是有__iter__
方法的对象,都是可迭代对象
可迭代的对象:Python内置str、list、tuple、dict、set、file都是可迭代对象。
lt = [1,2,3,4]
print(lt.__iter__())
# 打印结果:
<list_iterator object at 0x00000211EB7565C0>
迭代器对象
含有__iter__
和__next__
方法的对象就是迭代器对象
为什么要有迭代器对象:提供了 不依赖索引取值的手段
dic = {'a':1, 'b':2, 'c':3}
dic_iter = dic.__iter__()
print(dic_iter.__next__())
print(dic_iter.__next__())
print(dic_iter.__next__())
如果值取干净了,就会报错StopIteration
总结:
迭代器对象:执行可迭代对象的__iter__
方法,拿到的返回值就是迭代器对象。
特点:
- 内置
__next__
方法,执行该方法会拿到迭代器对象中的一个值 - 内置有
__iter__
方法,执行该方法会拿到迭代器本身 - 文件本身就是迭代器对象。
缺点:
- 取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
- 无法使用len()方法获取长度
for循环原理
for循环称为迭代器循环,in后面必须是可迭代对象
```python
dic = {'a':1, 'b':2, 'c':3}
dic_iter = dic.__iter__()
while True:
try:
print(dic_iter.__next__())
except Exception:
break
```
总结:
- 含有
__iter__
方法的就是可迭代对象,除了数字类型,其它都是可迭代对象。可迭代对象使用__iter__
就会变成迭代器。 - 含有
__next__
方法的就是迭代器对象,只有文件是迭代器对象。迭代器使用__iter__
依然是迭代器
三元表达式
x = 10
y = 20
if x > y:
print(x)
else:
print(y)
print(x if x > y else y) # 三元表达式
列表推导式
lt = [i for i in range(10)]
print(lt)
字典生成式
dic = {i:i for i in range(10)}
print(dic)
zip()方法
res = zip([1,2,3],['a','b','c']) # res是一个迭代器,__next__返回元组
print(res.__next__())
print(res.__next__())
print(res.__next__())
# 打印结果:
(1, 'a')
(2, 'b')
(3, 'c')
利用两个列表快速生成一个字典
lt1 = ['a', 'b', 'c']
lt2 = [1, 2, 3]
res = zip(lt1, lt2)
dic = {k: v for k, v in res}
print(dic)
# 打印结果:
{'a': 1, 'b': 2, 'c': 3}
生成器
生成器:
- 含有yield关键字的函数叫生成器。
- 生成器本质上就是一个自定义的迭代器
def f():
yield 1 # 一个yield相当于一个next,可以暂停函数
yield 2
f = f()
print(f.__next__())
print(f.__next__())
生成器表达式
f = (i for i in range(10))
for i in f:
print(i)
生成器表达式节省内存,能一个个取出值---> 相当于老母鸡下蛋
列表推导式,一下子就取出----> 相当于一筐鸡蛋
yield与return的比较:
- yield可以暂停函数,通过next取值
- return可以终止函数,通过调用函数拿到值
递归
函数f内部直接或间接调用函数f本身
def f(): # 死递归
a = 1
print(a)
f()
f()
每一次递归,不会结束函数,并且每一次递归都会开辟内存空间,如果一直开辟内存空间,内存就炸掉了,最多递归1000次。
真正的递归必须要有退出条件
count = 0
def func():
global count
count += 1
print(count)
if count == 100:
return
func()
func()