迭代器

可迭代协议和迭代器协议

  • 可迭代协议

    只要含有__iter__方法的对象都是可迭代的

  • 迭代器协议

    内部含有__next__和__iter__方法的就是迭代器

  • 关系

    1.可以被for循环的都是可迭代的

    2.可迭代的内部都有__iter__函数

    3.只要是迭代器,一定可迭代

    4.可迭代的对象使用__iter__方法就可以得到一个迭代器

    5.迭代器中的__next__方法可以一个一个的获取值

例子

  • 判断是否是可迭代类型

    可以被for循环的类型都有__iter__()函数

    dir()函数可以返回类型里面所有函数名称

     print('__iter__' in dir(int))  # result:False
     print('__iter__' in dir(bool))  # result:False
     print('__iter__' in dir(list))  # result:True
     print('__iter__' in dir(dict))  # result:True
     print('__iter__' in dir(set))  # result:True
     print('__iter__' in dir(tuple))  # result:True
     print('__iter__' in dir(enumerate([])))  # result:True
     print('__iter__' in dir(range(1)))  # result:True
  • 判断是否是迭代器

    isinstance()函数可以判断一个对象是否是指定类型的实例

    import collections
    
    print(isinstance([], collections.Iterator))  # result: False
    print(isinstance([], collections.Iterable))  # result: True
    print(isinstance([].__iter__(), collections.Iterator))  # result:True
  • 通过__next__()函数取值

     num_list = [1, 2, True, 5, 'hello']
     print(type(num_list.__iter__()))  # result:<class 'list_iterator'>
     iterator = num_list.__iter__()
     print(iterator.__next__())  # result:1
     print(iterator.__next__())  # result:2
     print(iterator.__next__())  # result:True
     print(iterator.__next__())  # result:5
     print(iterator.__next__())  # result:hello
     print(iterator.__next__())  # 抛异常StopIteration

    当迭代器的next()方法取不到值时会抛一个StopIteration异常

迭代器的好处

1.从容器类型对象中一个一个的取值,会把所有的值都取到

2.节省内存空间(迭代器并不会在内存中再占用一大块内存,而是随着循环 每次生成(next())一个)

生成器函数

定义

只要含有yield关键字的函数都是生成器函数

   注:yield不能和return共用且需要写在函数内

例子

  • 生成器函数的执行

    执行之后会得到一个生成器作为返回值

     import collections;
    
     def generator():
         yield 'a'
         yield 'b'
    
     result = generator()
     print(type(result))  # <class 'generator'>
     print(isinstance(result, collections.Iterable))  # True
     print(isinstance(result, collections.Iterator))  # True
     print(result.__next__())  # a
     print(result.__next__())  # b

    通过第10行可以看出,生成器也是迭代器

  • 监听文件输入

     def listen(filename):
         f = open(filename, encoding='utf-8')
         while True:
             line = f.readline()
             if line.strip():
                 yield line.strip()
    
     listenr = listen('generator_file.txt')
     for line in listenr:
         print('your input:', line)

生成器进阶

send()函数使用

生成器中send()函数可以让上一个执行的yied接收一个值

 def num_generator():
     i = 1
     num = yield i
     i += num
     yield i

 generator = num_generator()

移动平均数例子

 def avg_num():
     sum = 0
     count = 0
     avg = 0
     while True:
         num = yield avg
         sum += num
         count += 1
         avg = sum / count

 ave_generator = avg_num()
 ave_generator.__next__()
 print(ave_generator.send(10))  # 10.0
 print(ave_generator.send(20))  # 15.0
 print(ave_generator.send(30))  # 20.0
 print(ave_generator.send(60))  # 30.0

面试题

  • 写出下面代码的输出内容

    def add(n, i):
        return n + i
    
    def test():
        for i in range(4):
            yield i
    
    g = test()
    for n in [1, 10]:
        g = (add(n, i) for i in g)
    print(list(g))
  • 分析&结果
      # 循环可拆成如下代码
      n = 1
      g = (add(n, i) for i in g)
      n = 10
      # g = (add(n, i) for i in g(指向第3行的g))
      # g = (add(n, i) for i in (add(n, i) for i in g(第三行的g指向test())))
      g = (add(n, i) for i in (add(n, i) for i in test()))
      # 真正执行的时候 也就是list(g)的时候 n=10 将n替换为10结果如下:
      g = (add(10, i) for i in (add(10, i) for i in (0, 1, 2, 3)))
      g = (add(10, i) for i in (10, 11, 12, 13))
      g = (20, 21, 22, 23)
      print(list(g))

推导式

列表

 num_list = [1, 2, 3, 4]
 str_list = ['数字{}'.format(i) for i in num_list]
 print(str_list)  # ['数字1', '数字2', '数字3', '数字4']

字典

反转dic的key和value的顺序

dic = {1: 'a', 2: 'b', 3: 'c'}
reverse_dic = {dic[key]: key for key in dic}
print(reverse_dic)  # {'a': 1, 'b': 2, 'c': 3}

集合

输出集合中元组里面大于10的元素

 num_set = {(3, 4, 1, 5, 77, 5), (2, 3, 4, 56, 77, 6, 34)};
 result_set = {i for lst in num_set for i in lst if i > 10}
 print(result_set)  # {56, 34, 77}

python基础(9)-迭代器&生成器函数&生成器进阶&推导式的更多相关文章

  1. (转)python基础之迭代器协议和生成器(一)

    一 递归和迭代 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...

  2. python基础之 迭代器回顾,生成器,推导式

    1.迭代器回顾 可迭代对象:Iterable 可以直接作用于for循环的对象统称为可迭代对象:Iterable.因为可迭代对象里面存在可迭代协议,所以才会被迭代 可迭代对象包括: 列表(list) 元 ...

  3. python基础知识15---三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数

    阅读目录 一 三元表达式.列表推导式.生成器表达式 二 递归与二分法 三 匿名函数 四 内置函数 五 阶段性练习 一. 三元表达式.列表推导式.生成器表达式 1 三元表达式 name=input('姓 ...

  4. python基础之迭代器协议和生成器

    迭代器和生成器补充:http://www.cnblogs.com/luchuangao/p/6847081.html 一 递归和迭代 略 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个ne ...

  5. python基础之迭代器协议和生成器(二)

    一.什么是迭代器: 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器是一个可以记住遍历的位置的对象. 迭代器的 ...

  6. python基础之迭代器协议和生成器(一)

    一 递归和迭代 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...

  7. python 生成器 和生成器函数 以及各种推导式

    一.生成器    本质就是迭代器. 我们可以直接执⾏__next__()来执⾏ 以下⽣成器 一个一个的创建对象 创建生成器的方式: 1.生成器函数 2.通过生成器 表达式来获取生成器 3.类型转换(看 ...

  8. day 12 生成器和生成器函数以及各种推导式

    一.生成器    本质就是迭代器. 我们可以直接执⾏__next__()来执⾏ 以下⽣成器 一个一个的创建对象 创建生成器的方式: 1.生成器函数 2.通过生成器 表达式来获取生成器 3.类型转换(看 ...

  9. python基础知识-8-三元和一行代码(推导式)

    python其他知识目录 1.三元运算(三目运算) 三元运算符就是在赋值变量的时候,可以直接加判断,然后赋值格式:[on_true] if [expression] else [on_false]re ...

  10. Python基础之列表深浅复制和列表推导式

    一.列表深浅复制: 浅拷贝内存图如下: 深拷贝内存图如下: 二.列表推导式: 实例: """ 列表推导式 练习:exercise01 """ ...

随机推荐

  1. Spring task定时任务执行一段时间后莫名其妙停止的问题

    前因: 我写了一个小项目,主要功能是用Spring task定时任务每天定时给用户发送邮件.执行了几个月一直没有问题,前几天,莫名其妙的突然不再发送邮件了. 只好花费一些时间来查看到底是什么原因造成的 ...

  2. RabbitMQ随笔

    不管是官方还是能搜到的文章,使用MQ的基本思路都是这样: static void Main(string[] args) { //通过工厂建立连接 using (IConnection connect ...

  3. 剖析Elasticsearch集群系列之三:近实时搜索、深层分页问题和搜索相关性权衡之道

    转载:http://www.infoq.com/cn/articles/anatomy-of-an-elasticsearch-cluster-part03 近实时搜索 虽然Elasticsearch ...

  4. MyISAM和InnoDB区别 及选择

    MySQL默认采用的是MyISAM. MyISAM不支持事务,而InnoDB支持.InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,所以 ...

  5. 微信生成二维码 只需一个网址即刻 还有jquery生成二维码

    <div class="orderDetails-info"> <img src="http://qr.topscan.com/api.php?text ...

  6. day1 一、编程语言与计算机五大组成部分

    一.编程与编程语言 1.什么是编程语言 语言是一个事物与另一个事物沟通的介质. 编程语言是程序员与计算机沟通的介质. 2.什么是编程 编程就是程序员按照某种编程的语法规范将自己想让计算机做的事情表达出 ...

  7. db2 表空间扩容

    DB2表空间扩容 1 - Detect what tablespace has size issues db2 list tablespaces show detail 2 - Check the p ...

  8. {MySQL的逻辑查询语句的执行顺序}一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析

    MySQL的逻辑查询语句的执行顺序 阅读目录 一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析 一 SEL ...

  9. MySQL 安装 用户管理 常用命令

    MySQL目录 数据库概览   数据库介绍 Why Choose MySQL MySQL的前世今生 MySQL的安装   Windows安装MySQL5.721 installer版 Windows安 ...

  10. PHP之null

    null类型 特殊的null值表示一个变量没有值.null类型唯一可能的值是null. 在下列情况下一个变量被认为是null: ①.被赋值为null ②.尚未被赋值 ③被unset(). 语法 nul ...