zoukankan      html  css  js  c++  java
  • 迭代器

    1. 今日内容大纲

      1. global nonlocal

      2. 函数名的运用

      3. 新特性:格式化输出

      4. 迭代器:

        • 可迭代对象

        • 获取对象的方法

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

        • 小结

        • 迭代器

        • 迭代器的定义

        • 判断一个对象是否是迭代器

        • 迭代器的取值

        • 可迭代对象如何转化成迭代器

        • while循环模拟for循环机制

        • 小结

        • 可迭代对象与迭代器的对比

    2. 昨日内容回顾以及作业讲解

      1. 函数的参数:

        1. 实参角度:位置参数,关键字参数,混合参数。

        2. 形参角度:位置参数,默认参数,仅限关键字参数,万能参数。

        3. 形参角度参数顺序:位置参数,*args, 默认参数,仅限关键字参数,**kwargs.

      2. *的魔性用法:

        • 函数的定义时:代表聚合。

        • 函数的调用时:代表打散。

      3. python中存在三个空间:

        • 内置名称空间:存储的内置函数:print,input.......

        • 全局名称空间:py文件,存放的是py文件(除去函数,类内部的)的变量,函数名与函数的内存地址的关系。

        • 局部名称空间:存放的函数内部的变量与值的对应关系。

      4. 加载顺序:内置名称空间,全局名称空间, 局部名称空间(执行函数时)。

      5. 取值顺序:就近原则。LEGB.

        1. 局部作用域只能引用全局变量,不能修改。

           name = 'alex'
           def func():
            name = name + 'sb'
      6. 作用域:

        • 全局作用域:内置名称空间 + 全局名称空间。

        • 局部作用域:局部名称空间。

      7. 函数的嵌套

      8. globals() locals()

         

       

       

    3. 今日内容

      1. global nonlocal

        • 补充:

          默认参数的陷阱

           1  # 默认参数的陷阱:
           2  # def func(name,sex=''):
           3  #     print(name)
           4  #     print(sex)
           5  # func('alex')
           6  7  # 陷阱只针对于默认参数是可变的数据类型:
           8  # def func(name,alist=[]):
           9  #     alist.append(name)
          10  #     return alist
          11  #
          12  # ret1 = func('alex')
          13  # print(ret1,id(ret1))  # ['alex']
          14  # ret2 = func('太白金星')
          15  # print(ret2,id(ret2))  # ['太白金星']
          16 17  # 如果你的默认参数指向的是可变的数据类型,那么你无论调用多少次这个默认参数,都是同一个。
          18 19  # def func(a, list=[]):
          20  #     list.append(a)
          21  #     return list
          22  # print(func(10,))  # [10,]
          23  # print(func(20,[]))  # [20,]
          24  # print(func(100,))  # [10,100]
          25  # l1 = []
          26  # l1.append(10)
          27  # print(l1)
          28  # l2 = []
          29  # l2.append(20)
          30  # print(l2)
          31  # l1.append(100)
          32  # print(l1)
          33  #
          34  # def func(a, list= []):
          35  #     list.append(a)
          36  #     return list
          37  # ret1 = func(10,)  # ret = [10,]
          38  # ret2 = func(20,[])  # [20,]
          39  # ret3 = func(100,)  # ret3 = [10,100]
          40  # print(ret1)  # [10,]  [10,100]
          41  # print(ret2)  # 20,]  [20,]
          42  # print(ret3)  # [10,100]  [10,100]
          43

          局部作用域的坑:

           1  # 默认参数的陷阱:
           2  # def func(name,sex=''):
           3  #     print(name)
           4  #     print(sex)
           5  # func('alex')
           6  7  # 陷阱只针对于默认参数是可变的数据类型:
           8  # def func(name,alist=[]):
           9  #     alist.append(name)
          10  #     return alist
          11  #
          12  # ret1 = func('alex')
          13  # print(ret1,id(ret1))  # ['alex']
          14  # ret2 = func('太白金星')
          15  # print(ret2,id(ret2))  # ['太白金星']
          16 17  # 如果你的默认参数指向的是可变的数据类型,那么你无论调用多少次这个默认参数,都是同一个。
          18 19  # def func(a, list=[]):
          20  #     list.append(a)
          21  #     return list
          22  # print(func(10,))  # [10,]
          23  # print(func(20,[]))  # [20,]
          24  # print(func(100,))  # [10,100]
          25  # l1 = []
          26  # l1.append(10)
          27  # print(l1)
          28  # l2 = []
          29  # l2.append(20)
          30  # print(l2)
          31  # l1.append(100)
          32  # print(l1)
          33  #
          34  # def func(a, list= []):
          35  #     list.append(a)
          36  #     return list
          37  # ret1 = func(10,)  # ret = [10,]
          38  # ret2 = func(20,[])  # [20,]
          39  # ret3 = func(100,)  # ret3 = [10,100]
          40  # print(ret1)  # [10,]  [10,100]
          41  # print(ret2)  # 20,]  [20,]
          42  # print(ret3)  # [10,100]  [10,100]
          43

          global nonlocal

           1  global
           2  1, 在局部作用域声明一个全局变量。
           3  name = 'alex'
           4  5  def func():
           6      global name
           7      name = '太白金星'
           8      # print(name)
           9  func()
          10  print(name)
          11 12 13  def func():
          14      global name
          15      name = '太白金星'
          16  # print(name)
          17  print(globals())
          18  func()
          19  # print(name)
          20  print(globals())
          21 22  2. 修改一个全局变量
          23  count = 1
          24  def func():
          25      # print(count)
          26      global count
          27      count += 1
          28  print(count)
          29  func()
          30  print(count)
          31 32 33  nonlocal
          34 35  1. 不能够操作全局变量。
          36  count = 1
          37  def func():
          38      nonlocal count
          39      count += 1
          40  func()
          41  2. 局部作用域:内层函数对外层函数的局部变量进行修改。
          42 43  def wrapper():
          44      count = 1
          45      def inner():
          46          nonlocal count
          47          count += 1
          48      print(count)
          49      inner()
          50      print(count)
          51  wrapper()

           

      2. 函数名的运用

         1  # def func():
         2  #     print(666)
         3  #
         4  # # func()
         5  # # 1. 函数名指向的是函数的内存地址。
         6  # # 函数名 + ()就可以执行次函数。
         7  # # a = 1
         8  # # a()
         9  # # func()
        10  # # a = {'name': 'alex'}
        11  # # b = {'age' : 18}
        12  # # a = 1
        13  # # b = 2
        14  # # print(a + b)
        15  # print(func,type(func))  # <function func at 0x000001BA864E1D08>
        16  # func()
        17 18  # 2, 函数名就是变量。
        19  # def func():
        20  #     print(666)
        21 22  # a = 2
        23  # b = a
        24  # c = b
        25  # print(c)
        26  # f = func
        27  # f1 = f
        28  # f2 = f1
        29  # f()
        30  # func()
        31  # f1()
        32  # f2()
        33  #
        34  # def func():
        35  #     print('in func')
        36  #
        37  # def func1():
        38  #     print('in func1')
        39  #
        40  # func1 = func
        41  # func1()
        42  # a = 1
        43  # b = 2
        44  # a = b
        45  # print(a)
        46 47  # 3. 函数名可以作为容器类数据类型的元素
        48 49  # def func1():
        50  #     print('in func1')
        51  #
        52  # def func2():
        53  #     print('in func2')
        54  #
        55  # def func3():
        56  #     print('in func3')
        57  # # a = 1
        58  # # b = 2
        59  # # c = 3
        60  # # l1 = [a,b,c]
        61  # # print(l1)
        62  # l1 = [func1,func2,func3]
        63  # for i in l1:
        64  #     i()
        65 66  # 4. 函数名可以作为函数的参数
        67 68  # def func(a):
        69  #     print(a)
        70  #     print('in func')
        71  # b = 3
        72  # func(b)
        73  # print(func)
        74 75  # def func():
        76  #     print('in func')
        77  #
        78  # def func1(x):
        79  #     x()  # func()
        80  #     print('in func1')
        81  #
        82  # func1(func)
        83 84  # 5. 函数名可以作为函数的返回值
        85  def func():
        86      print('in func')
        87 88  def func1(x): # x = func
        89      print('in func1')
        90      return x
        91 92  ret = func1(func)  # func
        93  ret()  # func()
        94

         

      3. 新特性:格式化输出

         1  # %s format
         2  # name = '太白'
         3  # age = 18
         4  # msg = '我叫%s,今年%s' %(name,age)
         5  # msg1 = '我叫{},今年{}'.format(name,age)
         6  7  # 新特性:格式化输出
         8  # name = '太白'
         9  # age = 18
        10  # msg = f'我叫{name},今年{age}'
        11  # print(msg)
        12 13  # 可以加表达式
        14  # dic = {'name':'alex','age': 73}
        15  # msg = f'我叫{dic["name"]},今年{dic["age"]}'
        16  # print(msg)
        17 18  # count = 7
        19  # print(f'最终结果:{count**2}')
        20  # name = 'barry'
        21  # msg = f'我的名字是{name.upper()}'
        22  # print(msg)
        23 24  # 结合函数写:
        25  def _sum(a,b):
        26      return a + b
        27 28  msg = f'最终的结果是:{_sum(10,20)}'
        29  print(msg)
        30  # ! , : { } ;这些标点不能出现在{} 这里面。

         

        优点:

        1. 结构更加简化。

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

        3. 效率提升很多。

           

      4. 迭代器:

        • 可迭代对象

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

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

          可以进行循环更新的一个实实在在值。

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

          目前学过的可迭代对象?str list tuple dict set range 文件句柄

        • 获取对象的所有方法并且以字符串的形式表现:dir()

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

          1  s1 = 'fjdskl'
          2  # l1 = [1,2,3]
          3  # # print(dir(s1))
          4  # print(dir((l1)))
          5  # print('__iter__' in dir(s1))
          6  # print('__iter__' in dir(range(10)))
        • 小结

          • 字面意思:可以进行循环更新的一个实实在在值。

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

          • 判断一个对象是不是可迭代对象: '__iter__' in dir(对象)

          • str list tuple dict set range

          • 优点:

            1. 存储的数据直接能显示,比较直观。

            2. 拥有的方法比较多,操作方便。

          • 缺点:

            1. 占用内存。

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

               

        • 迭代器

        • 迭代器的定义

          • 字面意思:更新迭代,器:工具:可更新迭代的工具。

          • 专业角度:内部含有'__iter__'方法并且含有'__next__'方法的对象就是迭代器。

          • 可以判断是否是迭代器:'__iter__' and '__next__' 在不在dir(对象)

        • 判断一个对象是否是迭代器

          1  with open('文件1',encoding='utf-8',mode='w') as f1:
          2      print(('__iter__' in dir(f1)) and ('__next__' in dir(f1)))
          3  
        • 迭代器的取值

           1 s1 = 'fjdag'
           2 obj = iter(s1)  # s1.__iter__()
           3 # print(obj)
           4 # print(next(obj)) # print(obj.__next__())
           5 # print(next(obj)) # print(obj.__next__())
           6 # print(next(obj)) # print(obj.__next__())
           7 # print(next(obj)) # print(obj.__next__())
           8 # print(next(obj)) # print(obj.__next__())
           9 # print(next(obj)) # print(obj.__next__())
          10 
          11 # l1 = [11,22,33,44,55,66]
          12 # obj = iter(l1)
          13 # print(next(obj))
          14 # print(next(obj))
          15 # print(next(obj))
          16 # print(next(obj))
          17 # print(next(obj))
          18 # print(next(obj))

           

        • 可迭代对象如何转化成迭代器

          1 iter([1,2,3])
        • while循环模拟for循环机制

          1 l1 = [11,22,33,44,55,66,77,88,99,1111,1133,15652]
          2 # 将可迭代对象转化成迭代器。
          3 obj = iter(l1)
          4 while 1:
          5     try:
          6         print(next(obj))
          7     except StopIteration:
          8         break

           

        • 小结

          • 字面意思:更新迭代,器:工具:可更新迭代的工具。

          • 专业角度:内部含有'__iter__'方法并且含有'__next__'方法的对象就是迭代器。

          • 优点:

            1. 节省内存。

            2. 惰性机制,next一次,取一个值。

          • 缺点:

            • 速度慢。

            • 不走回头路。

        • 可迭代对象与迭代器的对比

          • 可迭代对象是一个操作方法比较多,比较直观,存储数据相对少(几百万个对象,8G内存是可以承受的)的一个数据集。

          • 当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。

          • 是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。

          • 当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。

    4. 今日总结

      1. 默认参数的坑,作用域的坑 ***

      2. 格式化输出 ***

      3. 函数名的应用。***

      4. 对比:迭代器是什么? 迭代器的优缺点。可迭代对象转化成迭代器。next取值. ***

    5. 明日内容

  • 相关阅读:
    [Effective Java读书笔记] 第二章 创建和销毁对象(1~7)
    [Guava官方文档翻译] 5. Guava的Object公共方法 (Common Object Utilities Explained)
    [Guava官方文档翻译] 4. 使用Guava Ordering排序 (Ordering Explained)
    iOS正则表达式
    ios UIKit动力
    iOS8 UISearchViewController搜索功能讲解
    APP被苹果APPStore拒绝的各种原因
    iOS tableViewCell plane格式下,接近section边缘不显示分割线却被复用解决办法
    企业证书APP发布流程
    iOS越狱包
  • 原文地址:https://www.cnblogs.com/zhangxiangning/p/10216506.html
Copyright © 2011-2022 走看看