Day 13 迭代器/生成器/列表推导式/字典生成式/递归
目录
迭代器
可迭代对象
内置有__iter__
方法的都叫做可迭代对象,数字类型没有__iter__
方法
name = 'tiny'.__iter__
lis = [1, 2].__iter__
dic = {'name': 'tiny', 'age': 18}.__iter__
tup = (1, 2).__iter__
se = {'a', 'b'}.__iter__
fa = open('test.txt', 'a+', encoding='utf8')
fa.__iter__
迭代器对象
- 可迭代对象执行
__iter__
方法所得到的返回值就是迭代器对象 - 只有文件本身是迭代器对象
dic = {'name': 'tiny', 'age': 18}
dic_iter = dic.__iter__
print(dic_iter.__next__)
print(dic_iter.__next__)
name
age
for循环原理
for循环称为迭代器循环,in后必须是可迭代的对象。
因为迭代器使用__iter__
后还是迭代器本身,因此for循环不用考虑in后的对象是可迭代对象还是迭代器对象。
由于对可迭代对象使用__iter__
方法后变成一个迭代器对象,这个迭代器对象只是占用了一小块内存空间,他只有使用__next__
后才会吐出一个一个值。如lis = [1,2,3,4,5,...]
相当于一个一个鸡蛋,而lis = [1,2,3,4,5,...].__iter__
相当于一只老母鸡,如果你需要蛋,只需要__next__
即可。
三元表达式
x = 10
y = 20
if x > y:
print(x)
else:
print(y)
三元表达式:
print(x) if x > y else print(y)
列表推导式
lt = []
# for i in range(10):
# lt.append(i)
# 列表推导式
lt = [i for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
字典生成式
dic = {i:i**2 for i in range(10)}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
zip()方法
返回一个zip对象,该对象的. next_()方法返回一个元组
第i个元素来自第i个迭代参数。.next ()
方法一直持续到参数序列中最短的可迭代值
已耗尽,然后引发StopIteration。
lis1 = ['a', 'b', 'c']
lis2 = [1, 2, 3, 4] #取短的序列
res = zip(lis1, lis2)
dic = {k:v for k,v in res}
{'a': 1, 'b': 2, 'c': 3}
生成器
含有yield关键字的函数叫做生成器,生成器的本质是一个迭代器
yield关键字
def func():
print(1)
yield
print(2)
yield 1
g = func()
print(g)
for i in g:
print(i)
1
None
2
1
yield与return的区别
- 相同点:两者都是在函数中使用,都可以返回值,并且返回值没有类型和个数限制
- 不同点:return只返回一次,yield可以暂停函数,并提供当前的返回值,返回多次值
迭代器套迭代器
def ge():
yield 1
yield 2
for i range(3):
yield i
g = ge()
for i in g:
print(i)
1
2
0
1
2
生成器表达式
把列表推导式的[]换成()就是生成器表达式了
t = (i for i in range(10))
print(t)
for i in t:
print(i, end='')
<generator object
0123456789
列表推导式与生成器的区别:
- 生成器占用内存空间要节省的多
递归
函数a内部直接调用函数a本身
递归的特性:
- 函数内部调用自己
- 必须有退出条件
- 递归必须要有规律
直接调用
直接函数内部调用本身
count = 0
def foo():
global count
count += 1
print(count)
if count == 5:
return
foo()
foo()
间接调用
通过其他方法间接调用函数自身
def bar():
print('from bar')
foo()
def foo():
print('from foo')
bar()
bar()
如何使用递归
二分法查找
from random import randint
nums = [randint(1, 100) for i in range(100)]
nums = sorted(nums)
print(nums)
def search(search_num, nums):
mid_index = len(nums) // 2
# print(nums)
if not nums:
print('not exists')
return
elif search_num > nums[mid_index]:
nums = nums[mid_index + 1:]
search(search_num, nums)
elif search_num < nums[mid_index]:
nums = nums[:mid_index]
search(search_num, nums)
else:
print('find it')
search(50,nums)