迭代器
# 1.什么是迭代器
	# 迭代器指的是迭代取值的工具,迭代是一个重复的过程,
    # 每次重复都是基于上一次的结果而继续的,单纯的重复并不是迭代
    
# 2.为何要有迭代器
	# 迭代器是用来迭代取值的工具,而涉及到把多个值循环取出来的类型
    # 有:列表、字符串、元组、集合、字典、文件
    l = [‘ycc‘,‘xixi‘,‘haha‘]
    count = 0
    while count < len(l):
        print(l[count])
        count += 1
        
        # 上述迭代取值的方式只适用于有索引的数据类型:列表、字符串、元组
        # 为了解决基于索引迭代取值的局限性,python必须提供一种能够不依赖于索引的取值方式,这就是迭代器
        
# 3.如何用迭代器
	# 可迭代对象:但凡内置有__iter__方法的都称为可迭代的对象
    # s1 = ‘abc‘
    # s1_iterator = s1.__iter__()
    # l = []
    # l_iterator = l.__iter__()
    # set1 = {1,2,3}
    # set1_iterator = set1.__iter__()
    # dic = {‘a‘:1,‘b‘:2,‘c‘:3}
    # dic_iterator = dic.__iter__()
    # tup = (1,2,3)
    # tup_iterator = tup.__iter__()
    # with open(‘a.txt‘,‘w‘) as f:
    #	f.__iter__()
    #   pass
    
# 4.例:
	s1 = ‘abc‘
    s1_iterator = s1.__iter__()  # 等价于 iter(s1)
    print(s1_iterator.__next())  # a
    print(s1_iterator.__next())  # b
    print(s1_iterator.__next())  # c
    print(s1_iterator.__next())  # error:StopIteration
    # 只有三个值取完就报错
    
# 可迭代对象与迭代器对象详解:
	1.可迭代对象(可以转换成迭代器的对象):内置有__iter__()方法的对象
    	可迭代对象.__iter__() = 迭代器对象
     2.迭代器对象:内置有__next__()并且内置有__iter__()
    	迭代器对象.__next__() = 得到的下一个值
        迭代器对象.__iter__() = 得到迭代器本身,说白了掉了跟没调一个用
        
# 1.
# d = {‘a‘:1,‘b‘:2,‘c‘:3}
# d_iterator = d.__iter__()
# print(d_iterator is d_iterator.__iter__())  # True  迭代器对象 = 迭代器对象.__iter__()
# 2.
# for循环的工作原理:for循环可称之为迭代器循环
	# 1. d.__iter__()得到一个迭代器对象
    # 2. 迭代器对象.__next__()得到一个返回值,然后将返回值赋给k
    # 3. 循环往复步骤2,直到抛出异常for循环会捕捉异常结束
    
	d = {‘a‘:1,‘b‘:2,‘c‘:3}
    for k in d:
        print(d)
        
    d_iterator = d.__iter__()
    while True:
        try:
            print(next(d_iterator))
        except StopIteration:
            break
            
    print(‘=============================>‘)
    d_iterator = d.__iter__()  # 这里必须再调一次迭代器功能,因为上面已经将值取完了
    while True:
        try:
            print(next(d_iterator))
        except StopIteration:
            break
            
# 3.
	print(list(‘hello‘))  # [‘h‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘] 原理同for循环
    
# 4.
# 可迭代对象:字符串、列表、字典、元组、集合、文件对象
# 迭代器对象:文件对象
# 可迭代对象只有调用内置方法.__iter__()才能变成迭代器对象
# 文件对象既是可迭代对象也是迭代器对象
# with open(‘user.txt‘,‘w‘) as f:
#     f.__iter__()
#     f.__next__()
#     pass
# 5.迭代器的优缺点总结
# 优点:
#     1.为序列和非序列类型提供了一种统一的迭代取值方式。
#     2.惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值,
#     就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,
#     如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。
# 缺点:
#     1.除非取尽,否则无法获取迭代器的长度
#     2.只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行next方法直到值取尽,
#       否则就会停留在某个位置,等待下一次调用next;若是要再次迭代同个对象,
#       你只能重新调用iter方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器
# ,    必然只会有一个循环能取到值
      
    
生成器
# 如何得到自定义的迭代器 
# 在函数内一旦存在yield关键字,调用函数并不会执行函数体代码,会返回一个生成器对象,生成器即自定义的迭代器
 def func():
     print(‘第一次‘)
     yield 1
     print(‘第二次‘)
     yield 2
     print(‘第三次‘)
     yield 3
     print(‘第四次‘)
 func()
 g = func()
 g.__iter__()
# # 会触发函数体代码的运行,然后遇到yield停下来,将yield后的值当作本次调用的结果返回
 res1 = g.__next__()
 print(res1)
 res2 = g.__next__()
 print(res2)
 res3 = g.__next__()
 print(res3)
# res4 = g.__next__()  # StopIteration
# ps:补充
# len(‘aaa‘)  # 等同于‘aaa‘.__len__()
# next(g)  # 等同于g.__next__()
# iter(可迭代对象)  # 等同于 可迭代对象.__iter__()
# 应用:
def my_range(start,stop,step=1):
    while start < stop:
        yield start
        start += step
g = my_range(1,5,2)
while True:
        try:
            print(next(g))
        except StopIteration:
            break
# for i in my_range(1,10,2):
#     print(i)
# ps:retrun 与 yield的区别:
#     有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,
#     但不同于return,函数一遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值。
函数递归
# 函数递归调用:是函数嵌套调用的一种特殊形式
# 具体是指:在调用函数的过程中,直接或间接的又调用到本身
# import sys   了解
# print(sys.getrecursionlimit())  # 1000  最多死循环1000次
# sys.setrecursionlimit()  # 这个方法可以将限制1000次进行修改
# 一、递归定义
    # 直接调用本身(死循环)
        def f1():
            print(‘是我自己‘)
            f1()
        f1()
    # 间接调用本身(死循环)
        def f1():
            print(‘===>f1‘)
            f2()
        def f2():
            print(‘===>f2‘)
            f1()
        f1()
        
    # 一段代码的循环运行的方案有两种
    	# 方案一:while、for循环
        	while True:
                print(11)
                print(22)
        # 方案二: 递归的本质就是循环
        	def f1():
                print(1)
                print(2)
                f1()
            f1()
            
# 二、要强调的一点是:
# 递归调用不应该无限的调用下去,应该在满足某种条件下结束递归调用
# 例:取小于10的数
	# 方案一 :while、for循环
    	count = 0
        while count < 10:
            print(count)
            count += 1
            
    # 方案二: 递归
    	def func(count):
            if count > 9:
                return
            count += 1
            func(count)
         func(0)
        
# 三、递归的两个阶段
# 回溯:一层一层调用下去
# 递推:满足某种结束条件,结束递归调用,然后一层一层返回
# 例:
	# age(5) = age(4)+10
    # age(4) = age(3)+10
    # age(3) = age(2)+10
    # age(2) = age(1)+10
    # age = 18
    
    def age(n):
        if age == 18:
            return 
        return age(n) = age(n-1)+10
    age()
    
# 四、递归函数的应用,打印出下面列表的所有元素
l = [1,[2,[3,[4,5,[6,[7,[8,9,10]]]]]]]
for x in l:
    # 如果是列表应该再循环再判断
    if type(x) is list:
        pass # 这里会套无数个判断
    else:
        print(x)
# 转换思路用递归        
def func(list1)
    for x in list1:
        if type(x) is list:
			func(x)
        else:
            print(x)
func(l)
    
三元表达式
def func(x,y):
    if x > y:
        return x
    else:
        return y
func()
# 三元表达式 简化函数体
# 格式:条件成立时要返回的值 if 条件 else 条件不成立时要返回的值
def func(x,y)
	return x if x > y else y
res = func(1,3)
print(res) # 3
生成式
# 1.列表生成式
	l = [‘alex_dsb‘,‘egon_dsb‘,‘lxx_dsb‘,‘jason_dsb‘,‘ycc‘]
    # 将列表中含‘dsb‘的筛选数来组成一个新列表
    # 方案一:for循环+if判断+append
    new_l = []
    for name in l:
        if name.endswith(‘dsb‘):
            new_l.append(name)
    print(new_l)
           
    # 方案二:生成式
    new_l1 = [name for name in l if name.endswith(‘dsb‘)]
    
    # 将后缀_dsb去掉
    new_l2 = [name.replace(‘_dsb‘,‘‘) for name in l]
    # 将后缀_dsb加上
    new_l3 = [name+‘_dsb‘ for name in new_l2]
    
# 2.字典生成式
	 dic = {‘name‘:‘ycc‘,‘age‘:27,‘gender‘:‘male‘}
     new_dic = {k:v for k,v in dic.items() if k != ‘gender‘}
     print(new_dic)
    
    items = [(‘name‘,‘ycc‘),(‘age‘,27),(‘hobbies‘,[‘play‘,])]
    new_items = {k:v for k,v in items if k != ‘hobbies‘}
    print(new_items)
    
# 3.集合生成式
     keys = [‘name‘,‘age‘,‘hobbies‘]
     new_keys = {k for k in keys}
     print(new_keys)
    
# 4.生成器生成式
    # g = (i for i in range(1,20) if i <18)
    # # 此刻g内部一个值也没有
    #
    # print(next(g))
    # print(next(g))
    # print(next(g))
    # print(next(g))
    # sum()的使用方法
    # print(sum({1, 2, 3}))  # 要放可变类型
    # 将a.txt中的字符个数和算出来
    # with open(‘user.txt‘,‘rt‘,encoding=‘utf-8‘) as f:
        # 方法一:
        # res = 0
        # for line in f:
        #     res += len(line)
        # print(res)
        # 方法二:生成式
        # print(sum([len(line) for line in f]))
        # 方法三:
        # g = (len(line) for line in f)
        # 此刻内部一个值也没有
        # print(sum(g))
        # 写成一行就是:
        # print(sum((len(line) for line in f)))
        # 简写,可以去掉重复的括号
        # print(sum(len(line) for line in f))
            
二分法
# 必须是从小到大排序的数字列表
# 如果没有排序,用.sort()将其排序
	nums = [-3,5,26,35,55,66,77,88,99,100]
    find_num = 88
    def binary_search(find_num,l):
        if find_num not in l:
            print(‘值不存在‘)
            return
        mid_index = len(nums) // 2
        mid_nums = l[mid_index]
        if find_num > mid_num:
            l = l[mid_index+1:]
            binary_search(find_num,l)
        elif find_num < mid_num:
            l = l[:mid_index]
            binary_search(find_num,l)
        else:
            print(‘find it‘)
    binary_search(find_num,nums)
原文:https://www.cnblogs.com/ccTracy2021/p/14964132.html