python迭代器(函数名的应用,新版格

2023-01-31 00:01:19 函数 迭代 新版
  1. 内容大纲

    1. 函数名的运用
    2. 新特性:格式化输出
    3. 迭代器:
      • 可迭代对象
      • 获取对象的方法 dir()
      • 判断一个对象是否是可迭代对象
      • 小结
      • 迭代器
      • 迭代器的定义
      • 判断一个对象是否是迭代器
      • 迭代器的取值
      • 可迭代对象如何转化成迭代器
      • while循环模拟for循环机制
      • 小结
      • 可迭代对象与迭代器的对比
  2. 详细内容:

    1. 函数名的运用:

      函数名的定义和变量的定义几乎一致,在变量的角度,函数名其实就是一个变量,具有变量的功能:可以赋值;但是作为函数名他也有特殊的功能就是加上()就会执行对应的函数,所以我们可以把函数名当做一个特殊的变量。

      1:函数名指向的是函数的内存地址,函数名 + () 就可以执行此函数
       a =1
       a()#TypeError: 'int' object is not callable  不可调用
      
       a = 1
       b = 2
       print(a + b)#3  a与b可以相加,与a,b这两个变量本身无关,与变量指向的对象有关。
      
       def func():
           print(666)
       func()#666  之所以func + () 可以执行,与func (函数名) 指向的内存地址有关。函数的内存地址()才是执行这个函数的关键
       print(func,type(func))#<function func at 0x000001CB29A71E18> <class 'function'>
      
      2:函数名就是变量(函数名可以赋值给其他变量)
       def func():
           print(666)
       f = func   #变量的赋值
       f1 = f
       f2 = f1
       f()#666
       func()#666
       f1()#666
       f2()#666
      
      
       def func():
           print('in func')
       def func1():
           print('in func1')
       func1 = func
       func1()#in func
      
      
      3:函数名可以作为容器类数据类型的元素
       def func1():
           print('in func1')
       def func2():
           print('in func2')
       def func3():
           print('in fnc3')
       l1 = [func1,func2,func3]
       for i in l1:
           i()
      # # in func1
      # # in func2
      # # in fnc3
      
      # #类比:
       a = 1
       b = 2
       c = 3
       l1 = [a,b,c]
       print(l1)#[1, 2, 3]
      
      4;函数名可以作为函数的参数
       def func(a):
           print(a)
           print('in func')
       b = 3
       func(b)
      # # 3
      # # in func
      
      
       def func():
           print('in func')
       def func1(x):
           x()
           print('in func1')
       func1(func)
      # # in func
      # # in func1
      
      5:函数名可以作为函数的返回值
       def func():
           print('in func')
       def func1(x):       # 传参相当于x = func
           print('in func1')
           return x
       ret = func1(func)
       ret()  #相当于func()     # ret, x, func都是指向的func这个函数的内存地址
      # # in func1
      # # in func
      
    2. 新特性:格式化输出

      [1]格式花输出 %s fORMat
      
       name = '太白'
       age = 18
       msg ='我叫%s,今年%s' %(name,age)
       msg1 = '我叫{},今年{}'.format(name,age)
       print(msg)#我叫太白,今年18
       print(msg1)#我叫太白,今年18
      
      
      [2]python3.6之后的新特性:格式化输出 F 或 f :
      
       name = '太白'
       age = 18
       msg = f'我叫{name},今年{age}'
       print(msg)#我叫太白,今年18
      
      (1)可以加任意表达式:
      
       dic = {'name':'alex','age':18}
       msg = f"我叫{dic['name']},今年{dic['age']}"
       print(msg)#我叫alex,今年18
      
       count = 7
       print(f'最终结果是:{count**2}')#最终结果是:49
       name = 'barry'
       msg = f'我的名字是{name.upper()}'
       print(msg)#我的名字是BARRY
      
       l1 = ['太白金星', 18]
       msg = f'姓名:{l1[0]},年龄:{l1[1]}.'
       print(msg)  # 姓名:太白金星,年龄:18.
      
      (2)结合函数写:可以用函数完成相应的功能,然后将返回值返回到字符串相应的位置
       def _sum(a,b):
           return a + b
       msg = f'最终的结果是:{_sum(10,20)}'
       print(msg)#最终的结果是:30
      
      (3)多行f:
        name = 'barry'
        age = 18
        ajd = 'handsome'
        speaker = f'Hi {name}.'\
                  f'You are {age} years old.'\
                  f'You are a {ajd} guy!'
        print(speaker)
      
      (4)其它:
      print(f"{{73}}")  # {73}
      print(f"{{{73}}}")  # {73}
      print(f"{{{{73}}}}")  # {{73}}
      
      注意: ! , : { } ;这些标点不能出现在{} 这里面。
      print(f'{;12}')  # 报错
      # 所以使用lambda 表达式会出现一些问题。
      # 解决方式:可将lambda嵌套在圆括号里面解决此问题。
       x = 5
       y = 4
      print(f'{(lambda x:x*2) }')#<function <lambda> at 0x000001C5278F1E18>   (lambda x:x*2)相当于函数的内存地址
      print(f'{(lambda x:x*2) (x)}')#10     函数内存地址+()  函数执行
      print(f'{(lambda x,y:x + y) (5,4)}')#9

      优点:

      1. 结构更加简化。

      2. 可以结合表达式,函数进行使用。

      3. 效率提升很多。

    3. 迭代器:

      • 可迭代对象:

        字面意思:对象?:python中一切皆对象。一个实实在在存在的值,对象。

        ​ 可迭代?:更新迭代。重复的,循环的一个过程,更新迭代每次都有新的内容,

        ​ 可迭代对象-->可以进行循环更新的一个实实在在值。

        专业角度:可迭代对象--> 内部含有'__iter__'方法的对象,可迭代对象。

        目前学过的可迭代对象:str bytes list tuple dict set range

      • 获取对象的所有方法并且以字符串的形式表现:dir() 会返回一个列表,这个列表中含有该对象的以字符串的形式所有方法名

      • 判断一个对象是否是可迭代对象:

        '__iter__'`  in dir(对象)
        
         s1 = 'asdfghj'
         print(dir(s1))
         print('__iter__' in dir(s1))#True
        
         l1 = [1,2,3]
         print(dir(l1))
         print('__iter__' in dir(l1))#True
        
         b1 = b'wert'
         print(dir(b1))
         print('__iter__' in dir(b1))#True
        
         print('__iter__' in dir(range(10)))#True
        
      • 优缺点:

        • 优点:

          1. 存储的数据直接能打印显示,比较直观。
          2. 拥有的方法比较多,操作方便。
        • 缺点:

          1. 占用内存。

          2. 不能直接通过for循环进行取值,不能直接取值(索引,key除外)。

            • 可迭代对象不能迭代取值(除去索引,key以外)
            • for内部先将可迭代对象转化为迭代器,然后用next对迭代器取值。
      • 迭代器

      • 迭代器的定义

        • 字面意思:更新迭代,器:工具:可更新迭代的工具。
        • 专业角度:内部含有'__iter__'方法并且含有'__next__'方法的对象就是迭代器。
        • 迭代器是这样的对象:实现了无参数的__next__方法,返回序列中的下一个元素,如果没有元素了,那么抛出StopIteration异常.Python中的迭代器还实现了__iter__方法,因此迭代器也可以迭代。 出自《流畅的python》
        • 可以判断是否是迭代器:'__iter__' and '__next__' 在不在dir(对象)
      • 判断一个对象是否是迭代器:

        with open('文件1',encoding='utf-8',mode='w') as f1:
            print(('__iter__' in dir(f1)) and ('__next__' in dir(f1)))
        
        目前学过的迭代器:文件句柄
        
         s = 'asdff'
         print('__next__' in dir(s))# False
      • 转化,取值 :

        • 1.可迭代对象转化为迭代器:对可迭代对象操作,形成一个迭代器。str还是str,list还是list

        • 2.对迭代器取值:一个next() 取一个值,少一个next()可以,多一个就会报错.

          • 可迭代对象是不可以一直迭代取值的(除去用索引,切片以及Key),但是转化成迭代器就可以了,迭代器是利用__next__()进行取值

          • 迭代器利用next取值:一个next取对应的一个值,如果迭代器里面的值取完了,还要next,那么就报StopIteration的错误。
        s1 = 'asdf'
        obj = iter(s1)  #转化为迭代器
        print(obj)#<str_iterator object at 0x000002216DB77828>
        print(next(obj))#a
        print(next(obj))#s
        print(next(obj))#d
        print(next(obj))#f
        
        s1 = 'asdf'
        obj = s1.__iter__()   #转化为迭代器
        print(obj)#<str_iterator object at 0x000001FE307877F0>
        print(obj.__next__())#a
        print(obj.__next__())#s
        print(obj.__next__())#d
        print(obj.__next__())#f
        
        
        l1 = [11,22,33,44,55,66]
        obj = l1.__iter__()
        print(obj)
        print(obj.__next__())  #对迭代器取值
        print(obj.__next__())
        print(obj.__next__())
        print(obj.__next__())
        print(obj.__next__())
        print(obj.__next__())
        
        l1 = [11,22,33,44,55,66]
        obj = iter(l1)
        print(obj)
        print(next(obj))  #对迭代器取
        print(next(obj))
        print(next(obj))
        print(next(obj))
        print(next(obj))
        print(next(obj))
        
        
        #
         l1 = [11,22,33,44,55,66,77,88,99,1010,1111,1212]
         count = 0
         for i in l1:
             if count == 4:
                 break
             else:
                 print(i)
             count += 1
        # # 11
        # # 22
        # # 33
        # # 44
        
         count = 0
         for i in l1:
             if count == 6:
                 break
             else:
                 print(i)
             count += 1
        # # 11
        # # 22
        # # 33
        # # 44
        # # 55
        # # 66
        
        
        
        #迭代器永远会记住取值的位置
         l1 = [11,22,33,44,55,66,77,88,99,1010,1111,1212]
         obj = iter(l1)
         for i in range(4):
             print(next(obj))
        # # 11
        # # 22
        # # 33
        # # 44
        
         for i in range(6):
             print(next(obj))
        # # 55
        # # 66
        # # 77
        # # 88
        # # 99
        # # 1010
        
        
         l1 = [11,22,33,44,55,66,77,88,99,1010,1111,1212]
         for i in l1:
             print(i)
        
        
      • while循环模拟for循环机制【面试经常考】

        将可迭代对象转换成迭代器,然后利用next进行取值,最后利用异常处理处理StopIteration抛出的异常
        l1 = [11,22,33,44,55,66,77,88,99,1111,1133,15652]
        # 将可迭代对象转化成迭代器。
        obj = iter(l1)
        while 1:
            try:
                print(next(obj))
            except StopIteration:
                break
      • 小结:

        • 字面意思:更新迭代,器:工具:可更新迭代的工具。
        • 专业角度:内部含有'__iter__'方法并且含有'__next__'方法的对象就是迭代器。
        • 优点:
          1. 节省内存。
          2. 惰性机制, next一次,取一个值,绝不过多取值。
        • 缺点:
          • 速度慢。
          • 不走回头路。 取值时不走回头路,只能一直向下取值
      • 可迭代对象与迭代器的对比:

        • 可迭代对象:可迭代对象是一个操作方法比较多,比较直观,存储数据相对少(几百万个对象,8G内存是可以承受的)的一个数据集。
        • 应用:当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。
        • 迭代器:迭代器是非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。
        • 应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。
  3. 总结

    1. 格式化输出 ***
    2. 函数名的应用。***
    3. 对比:迭代器是什么? 迭代器的优缺点。可迭代对象转化成迭代器。next取值. ***

相关文章