zoukankan      html  css  js  c++  java
  • python_可迭代对象,迭代器,生成器

    一。可迭代对象

    概念:可以用for操作的对象都是可迭代对象

    举例:list tuple str set dict  都是可迭代对象

    如何判断是否是可迭代对象:

      方法一:isinstance(obj,Iterable) ,需要先导入Iterable(from typing import Iterable)

          

      方法二:有__iter__属性就是可迭代对象

        print(hasattr(list, "__iter__"))

      print(hasattr(tuple, "__iter__"))
      print(hasattr(str, "__iter__"))
      print(hasattr(set, "__iter__"))
      print(hasattr(dict, "__iter__"))


    #不可迭代对象

    for i in int(1): #会报错:TypeError: 'int' object is not iterable
    print(i)

    可迭代对象range()的实现方法:

      


    def my_range(stop):
    """模拟了python2中的range"""
    value = 1
    result = []
    while value < stop:
    result.append(value)
    value += 1
    return result


    # python2 中有xrange这个函数
    # python3 中把python2 rangexrange 整合为 "range"

    if __name__ == '__main__':
    # print(my_range(10))

    print(isinstance(my_range(10), Iterable))

    # 如果输入的数字过大就会很慢
    # print(my_range(999999999999999999))

    二。迭代器

    #如何判断某个对象是不是迭代器
    #方法一:isinstance(obj,Iterator) ,需要先导入Iterator
    #方法二:看对象有没有__iter__属性和__next__属性
    #迭代器协议:
    #1。迭代器类型必须实现 __iter__ __next__ __next__python2中是next,没有下滑线)
    #2__iter__ 方法必须返回self
    #3__next__必须返回下一个值,如果没有下一个抛出StopIteration异常
    from typing import Iterator

    obj = range(1,2)
    obj1= iter(range(1,2))

    #方法一:
    print(isinstance(obj,Iterator)) #False

    print(isinstance(obj1,Iterator)) #True

    print(isinstance([1,2,3],Iterator)) #False

    #方法二:
    for attr in dir(list):
    print(attr) #只有:__iter__属性

    for attr in dir(obj1):
    print(attr) #有:"__iter__" "__next__" 属性

    三。生成器

    #生成器的意义:为了快速创建一个迭代器
    # yield的关键字,来实现快速创建迭代器,生成器一定是一个迭代器
    #yield用法:在函数中使用
    #如果一个函数中有yield关键字,调用函数的时候不会执行函数的内容,会返回一个对象(这个对象类型是生成器类)

    四:自己实现一个生成器

    # 手动实现1-3的平方,返回1 4 9
    result = []
    for i in [1, 2, 3]:
    result.append(i * i)
    print(result)


    # 第一种:迭代器实现
    class Squares(object):
    def __init__(self, start, stop):
    self.start = start
    self.stop = stop

    def __iter__(self):
    return self

    def __next__(self):
    if self.start > self.stop:
    raise StopIteration
    current = self.start * self.start
    self.start += 1
    return current


    # 第第二种:生成器实现
    def squares(start, stop):
    for i in range(start, stop+1):
    yield i * i

    #第三种:
    squares2 = (i*i for i in range(1,4))

    #第二种方法和第三种方法对比:都是一样的类型 ,返回的都是:<class 'generator'>
    print(type(squares(1,4)))
    print(type(squares2))
    if __name__ == '__main__':
    #迭代器实现
    # iterator = Squares(1, 3)
    # for i in result:
    # print(i)

    #生成器实现
    iterator = squares(1, 3)
    for i in result:
    print(i)

    五:生成器的执行过程

    def f():
    print("开始执行")
    yield 1
    print("~~~~~~~~~~")
    yield 2


    def f2():
    result = []
    result.append(1)
    result.append(2)
    return result


    #当要访问生成器的__next__方法时,函数会变成 running 状态,当执行完成yield时,函数变成非running状态(即挂起)
    # 只有再次执行生成器的__next__方法时函数才会唤醒
    #疑问:什么情况下会执行生成器对象的__next__方法那?
    # (获取生成器下一个值的时候【参考f()f2(),这两个方法最终结果是一样的,在执行f()时第二次 yield 2 就是获取下一个值,也就是执行__next__】)
    if __name__ == '__main__':
    obj = f()
    #如果有yield返回的是 generator 对象,如果没有yield 返回的是"开始执行"
    print(obj)
    print(type(obj))
    print(obj.__next__())
    print(obj.__next__())

    #yield return区别
    #共同点:都是python的关键字
    #不同点:return 是结束函数并返回值,yield是暂时离开函数
    #方法一:isinstance(obj,Iterable) ,需要先导入Iterable
    爱折腾的小测试
  • 相关阅读:
    MySQL常用函数介绍
    SQL语法基础之DROP语句
    MySQL常见报错汇总
    SQL语法基础之SELECT
    SQL语法基础之ALTER语句
    OpenStack技术栈-OpenStack的基础原理概述
    体验Hadoop3.0生态圈-CDH6.1时代的来临
    Windows下强制删除文件或文件夹(解除文件占用/Unlock)
    foreach Transform 同时chils.setParent引起的bug
    CharacterController平滑移动到某点
  • 原文地址:https://www.cnblogs.com/newsss/p/14583909.html
Copyright © 2011-2022 走看看