day-13
目录
1. 迭代器
python中一切皆对象
迭代器和装饰器不同,迭代器只是一个称呼而已。
1.1 可迭代对象
含有 .__iter__
方法的数据类型叫做可迭代对象,除了数字类型,所有数据类型都是可迭代对象。
x = 10 # 不是可迭代对象
s = 'abc'
s.__iter__()
lt = [1, 2, 3]
lt.__iter__()
tup = (1,)
tup.__iter__()
dic = {'a': 1}
dic.__iter__()
se = {1}
se.__iter__()
fw = open('test.txt', 'a+', encoding='utf8')
fw.seek(0, 0)
fw.__iter__()
1.2 迭代器对象
含有 .__iter__
和 .__next__
方法的对象就是迭代器对象,只有文件是迭代器对象
dic = {'a': 1, 'b': 2, 'c': 3}
dic_iter = dic.__iter__() # 2.其他类型都需要这样间接使用
print(dic_iter.__next__())
print(dic_iter.__next__())
print(dic_iter.__next__())
fw = open('test.txt', 'a+', encoding='utf8')
fw.seek(0, 0)
fw.__iter__()
fw.__next__() # 1.文件类型可以直接使用 .__next__() 方法
print(fw.__next__())
print(fw.__next__())
print(fw.__next__())
运行结果:
a
b
c
------------------------------
1
2
3
Process finished with exit code 0
1.2.1 迭代器对象的作用
提供了一种不依赖索引取值的手段。
1.2.2 for 循环的原理
# for循环原理(for循环本质就是一个while循环,只不过是一个一定可控的while循环)
dic = {'a': 1, 'b': 2, 'c': 3} # 要求逐个取出字典的 key
dic_iter = dic.__iter__()
while True:
try:
print(dic_iter.__next__())
except StopIteration:
break
# print('-'*30)
for i in dic: # for循环 --> 迭代循环
print(i)
# 标准版
# def for(iterable):
# iterator = iterable.__iter__()
# while True:
# try:
# print(iterator.__next__())
# except StopIteration:
# break
a
b
c
------------------------------
a
b
c
Process finished with exit code 0
1.3 总结
- 可迭代对象:
- 含有
.__iter__
方法叫做可迭代对象 - 除了数字类型都是可迭代对象
- 可迭代对象使用
.__iter__
变成迭代器 - 可迭代对象不一定是迭代器对象
- 含有
- 迭代器对象:
- 含有
.__iter__
和.__next__
方法叫做迭代器对象 - 只有文件是迭代器对象
- 迭代器使用
.__iter__
依然是迭代器 - 迭代器对象一定是可迭代对象
- 含有
2. 三元表达式
格式:条件成立时的返回值 if 条件 else 条件不成立时的返回值
x = 10
y = 20
if x > y:
print(x)
else:
print(y)
使用三元表达式:
print(x) if x > y else print(y)
3. 列表推导式
创建一个列表
lt = []
for i in range(10):
lt.append(i)
使用列表推导式:
lt = [i for i in range(10)]
lt = [i ** 2 for i in range(10)] # in 后面加可迭代类型
4. 字典生成式
4.1 字典生成式
生成一个列表:
dic = {}
for i in range(10):
dic[i] = i ** 2
使用字典生成式:
dic = {i:i**2 for i in range(10)}
4.2 zip()方法
lt1 = ['a', 'b', 'c']
lt2 = [1, 2, 3]
dic = {k: v for k, v in zip(lt1, lt2)}
print(dic)
zip()
方法的说明:
res = zip([1, 2, 3], [4, 2, 3, 4, 2, 3, 4, 2, 3],
'abcadsfasdfasdf') # res是一个迭代器,__next__返回元组
print(res.__next__()) # type:tuple
print(res.__next__()) # type:tuple
print(res.__next__()) # type:tuple
打印结果:
(1, 4, 'a')
(2, 2, 'b')
(3, 3, 'c')
Process finished with exit code 0
5. 生成器
生成器:本质上是迭代器,它提供了一种方便的自定义迭代器的途径。
含有 yield
关键字的函数叫做生成器
5.1 生成器和函数的区别
def func():
print(1)
def ge():
yield 1
print(func)
print(ge)
print('-' * 30)
print(func())
print(ge())
运行结果:
<function func at 0x00000221B4673798> # 打印出了函数 func 的内存地址
<function ge at 0x00000221B4673828> # 打印出了函数 ge 的内存地址
------------------------------
1
None # func() 调用了函数,并得到了默认的返回值 None
<generator object ge at 0x00000221B4674048> # ge() 返回了生成器对象的地址,并没有执行里面的代码
Process finished with exit code 0
5.2 生成器的特性
- 生成器的本质是迭代器
def ge():
yield 1 # 一个yield相当于一个next; 暂停函数
yield 2
yield 3
g = ge() # 得到一个生成器
print(g.__next__())
print(g.__next__())
print(g.__next__())
运行结果:
1
2
3
Process finished with exit code 0
yield
的特性- 暂停函数
- 通过
.__next__()
取值
5.3 练习-简单的 range 方法
def range(start):
count = 0
while count < start:
yield (count)
count += 1
g = range(3)
print(g.__next__())
print(g.__next__())
print(g.__next__())
6. 生成器表达式
生成一个生成器:
# 生成器表达式
g = (i for i in range(5))
生成器表达式和列表推导式
# 生成器表达式
g = (i for i in range(5)) # 节省内存空间,需要用的时候取出来
# 列表推导式
lt = [i for i in range(5)] # 一次性生成数据,占用内存空间
7. 递归
-
递归:函数内部直接或间接的又调用了函数本身
# 这种形式叫做递归 def a(): x = 1 print(x) a() a()
由于每一次的递归,都没有结束函数的条件,并且每一次递归,都会开辟新的内存空间存放变量值,一直这样的话内存会爆掉,所以 python 给了限制最多递归1000次。
-
真正的递归必须有退出的条件
count = 0 def a(): global count count += 1 print(count) if count == 5: return a() a()
运行结果:
1 2 3 4 5 Process finished with exit code 0
7.1 总结
递归:
- 函数内部调用函数自己
- 必须要有退出条件
- 递归必须要有规律