Python之路——迭代器与生成器

一、迭代器

  1 # -*- encoding:utf-8 -*-
  2
  3
  4 # dir([1,2].__iter__())是列表迭代器中实现的所有方法,dir([1,2])是列表中实现的所有方法
  5 # print(dir([1,2].__iter__()))
  6 # print(dir([1,2]))
  7 # print(set(dir([1,2].__iter__()))-set(dir([1,2])))   # {‘__length_hint__‘, ‘__setstate__‘, ‘__next__‘}
  8
  9 # iter = [1,2,3,4,5,6].__iter__()
 10 # print(iter.__length_hint__())
 11 # print(iter.__next__())
 12 # print(iter.__next__())
 13 # print(iter.__length_hint__())   # 获取迭代器中剩余元素的长度
 14 #
 15 # print(‘**‘,iter.__setstate__(0))    # 根据索引值指定从哪里开始迭代
 16 # print(iter.__next__())
 17 # print(iter.__next__())  # 一个一个的取值
 18 # print(iter.__next__())
 19 # print(iter.__next__())
 20
 21 # l = [1,2,3,5]
 22 # l_iter = l.__iter__()
 23 # item = l_iter.__next__()
 24 # print(item)
 25 # item = l_iter.__next__()
 26 # print(item)
 27 # item = l_iter.__next__()
 28 # print(item)
 29 # item = l_iter.__next__()
 30 # print(item)
 31 # item = l_iter.__next__()    # 如果迭代器里已经没有元素了,会抛出一个StopIteration异常
 32 # print(item)
 33
 34 # l = [1,2,3,4]
 35 # l2 = l.__iter__()
 36 # while True:
 37 #     try:
 38 #         item = l2.__next__()
 39 #         print(item)
 40 #     except StopIteration:
 41 #         print(‘迭代完毕‘)
 42 #         break
 43
 44 # 迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法
 45
 46 # range()
 47 # print(‘__next__‘ in dir(range(12))) # False
 48 # print(‘__iter__‘ in dir(range(12))) # True
 49
 50 # from collections import Iterator
 51 # print(isinstance(range(12),Iterator))   # False , 验证range执行之后得到的结果不是一个迭代器
 52
 53 # 为何要有for循环
 54
 55 # l = [1,2,3]
 56 # index = 0
 57 # while index < len(l):
 58 #     print(l[index])
 59 #     index += 1
 60
 61 # 序列类型字符串,列表,元组都有下标,用上述方式访问,perfect!
 62 # 但是对于字典、集合、文件对象这种非序列型类型,就得使用for循环了。
 63 # for循环就是基于迭代器协议提供了一个统一的可以遍历所有对象的方法,
 64 # 即在遍历之前,先调用对象的__iter__方法将其转换成一个迭代器,
 65 # 然后使用迭代器去循环访问
 66
 67 # 迭代器的好处是可以节省内存
 68
 69 # print(‘__iter__‘ in dir(int))   # False
 70 # print(‘__iter__‘ in dir(bool))  # False
 71 # print(‘__iter__‘ in dir(list))  # True
 72 # print(‘__iter__‘ in dir(dict))  # True
 73 # print(‘__iter__‘ in dir(set))   # True
 74 # print(‘__iter__‘ in dir(tuple)) # True
 75 # print(‘__iter__‘ in dir(enumerate([]))) # True
 76 # print(‘__iter__‘ in dir(range(2))) # True
 77 # print(‘__next__‘ in dir(range(2))) # False
 78 # print(‘__next__‘ in dir(dict))  # False
 79
 80 # g = range(10).__iter__()
 81 # print(g.__next__())
 82 # print(g.__next__())
 83 # print(g.__next__())
 84 # print(g.__next__())
 85 # print(g.__next__())
 86 # print(g.__next__())
 87 from collections import Iterator
 88 from collections import Iterable
 89
 90 # class A:
 91 #     def __iter__(self): pass
 92 #     def __next__(self): pass
 93 #
 94 # a = A()
 95 # print(isinstance(a,Iterator))   # True
 96 # print(isinstance(a,Iterable))   # True
 97
 98 # class A:
 99 #     def __iter__(self): pass
100 #     #def __next__(self): pass
101 #
102 # a = A()
103 # print(isinstance(a,Iterator))   # False
104 # print(isinstance(a,Iterable))   # True    含有__iter__方法,是可迭代的,可迭代的,不一定是迭代器
105
106 # class A:
107 #     # def __iter__(self): pass
108 #     def __next__(self): pass
109 #
110 # a = A()
111 # print(isinstance(a,Iterator))   # False
112 # print(isinstance(a,Iterable))   # False   不含有__iter__方法,是不可迭代的
113
114 # 可以被for循环的都是可迭代的
115 # 可迭代的内部都有__iter__方法
116 # 只要是迭代器,一定可迭代
117 # print(range(10).__iter__())
118
119 # for
120 # 只有可迭代对象才能用for
121 # b = [].__iter__()
122 # a = b.__iter__()
123 # c = [].__iter__().__iter__()
124 # print(b)
125 # print(a)
126 # print(c)

二、生成器

# -*- encoding:utf-8 -*-

# 在某些情况下,我们想要像迭代器那样节省内存,就只能自己写。
# 我们自己写的这个能实现迭代器功能的东西就叫生成器

# Python中提供的生成器:
# 1.生成器函数:常规函数定义,但是使用yield语句返回结果,而不是return语句。
#   yield语句一次返回一个结果,在那个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行
# 2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
# yield 和return不能共用

# 初识生成器
# import time
# def generator_fun1():
#     a = 1
#     print(‘现在定义了a变量‘)
#     yield a
#     b = 2
#     print(‘现在定义了b变量‘)
#     yield b
#
# g1 = generator_fun1()   # generator_fun1() 返回一个可迭代的对象
# print(‘g1: ‘,g1)    # g1: <generator object generator_fun1 at 0x00000250C7EBE4C0>
#
# print(next(g1))
# time.sleep(1)
# print(next(g1))
# 输出:
# 现在定义了a变量
# 1
# 现在定义了b变量
# 2

# 生成器好处:不会一下子在内存中生成太多数据

# 初识生成器二
# def produce():
#     ‘‘‘生成衣服‘‘‘
#     for i in range(1,200):
#         yield ‘生成了第%s件衣服‘%i
#
# product_g = produce()
# print(product_g.__next__())
# print(product_g.__next__())
# print(product_g.__next__())
# num = 0
# for i in product_g:
#     print(i)
#     num += 1
#     if num == 5:
#         break

# 生成器监听文件输入????????????????????
# import time
# def tail(filename):
#     f = open(filename,encoding=‘utf-8‘)
#     f.seek(0,2) # 从文件末尾算起
#     while 1:
#         line = f.readline() # 读取文件中新的文本行
#         if not line.strip():
#             time.sleep(0.1)
#             continue
#         yield line.strip()
# tail_g = tail(‘tmp‘)
# for line in tail_g:
#     print(line)

# import time
# def tail(filename):
#     f = open(filename,encoding=‘utf-8‘)
#     f.seek(0,2)
#     while 1:
#         line = f.readline().strip()
#         if not line:
#             time.sleep(0.1)
#             continue
#         yield line
# tail_g = tail(‘tmp‘)
# for line in tail_g:
#     print(line)

# 计算移动平均值
# def averager():
#     total = 0.0
#     count = 0
#     average = None
#     while True:
#         term = yield average
#         total += term
#         count += 1
#         average = total/count
#
# g_avg = averager()
# next(g_avg)
# print(g_avg.send(10))# 先send一个值,再执行next函数
# print(g_avg.send(30))
# print(g_avg.send(50))

# 计算移动平均值二
# def init(func):
#     def inner(*args,**kwargs):
#         g = func(*args,**kwargs)
#         next(g)
#         return g
#     return inner
# @init
# def averager():
#     total = 0.0
#     count = 0
#     average = None
#     while True:
#         term = yield average
#         total += term
#         count += 1
#         average = total/count
#
#
# g_avg = averager()
#
# print(g_avg.send(10))
# print(g_avg.send(30))
# print(g_avg.send(50))

# yield from
# def gen1():
#     for c in "AB":
#         yield c
#     for i in range(3):
#         yield i
# print(list(gen1())) # [‘A‘, ‘B‘, 0, 1, 2]
#
# def gen2():
#     yield from ‘AB‘
#     yield from range(3)
# print(list(gen2())) # [‘A‘, ‘B‘, 0, 1, 2]

#列表推导式和生成器表达式
# egg_list = [‘鸡蛋%s‘ %i for i in range(10)] # 列表解析
# print(egg_list)
#
# laomuji = (‘鸡蛋%s‘ %i for i in range(10)) # 生成器表达式
# print(laomuji)
# print(next(laomuji))    # next()本质就是调用__next__
# print(laomuji.__next__())
# print(next(laomuji))

#总结
# 1.把列表解析的[]换成()得到的就是生成器表达式
# 2.列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
# 3.Python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议
#   访问对象的。例如,sun函数是python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器的协议,
#   所以,我们可以直接这样计算一系列值的和:
# print(sum(x ** 2 for x in range(4)))

三、生成器进阶练习

  1 # -*- encoding:utf-8 -*-
  2 # def generator():
  3 #     print(123)
  4 #     content = yield 1
  5 #     print(‘=====‘,content)
  6 #     print(456)
  7 #     arg = yield 2
  8 #     print(arg)
  9 #     yield
 10
 11 # g1 = generator()
 12 # g2 = generator()
 13 # g1.__next__()
 14 # g2.__next__()
 15 # print(‘***‘,generator().__next__())
 16 # print(‘***‘,generator().__next__())
 17
 18 # g = generator()
 19 # ret = g.__next__()
 20 # print(ret)
 21 # ret = g.send(‘hello‘)
 22 # print(ret)
 23 # print(g.send(1234))
 24
 25 # send 获取下一个值的效果和next基本一致
 26 # 只是在获取下一个值的时候,给上一个yield的位置传递一个数据
 27 #使用send的注意事项
 28     # 第一次使用生成器的时候,是用next获取下一个值
 29     # 最后一个yield不能接受外部的值
 30
 31 # def init(func):
 32 #     def inner(*args,**kwargs):
 33 #         g = func(*args,**kwargs)
 34 #         g.__next__()
 35 #         return g
 36 #     return inner
 37 # @init
 38 # def averager():
 39 #     sum = 0.0
 40 #     count = 0
 41 #     average = 0
 42 #     while 1:
 43 #         temp = yield average
 44 #         sum += temp
 45 #         count += 1
 46 #         average = sum/count
 47 # g = averager()
 48 # print(g.send(10))
 49 # print(g.send(30))
 50 # print(g.send(5))
 51
 52 #yield from
 53 # def gnrator():
 54 #     a = ‘AB‘
 55 #     for i in a:
 56 #         yield i
 57 #     b = [1,2,3]
 58 #     for i in b:
 59 #         yield i
 60 # g = gnrator()
 61 # for i in g:
 62 #     print(i)
 63
 64 # def gnrator2():
 65 #     yield from ‘AB‘
 66 #     yield from [1,2,3]
 67 # g = gnrator2()
 68 # for i in g:
 69 #     print(i)
 70
 71 # 列表推导式
 72 # egg_list = [‘egg%s‘ %i for i in range(10)]
 73 # print(egg_list)
 74 # print([i*i for i in range(1,10)])
 75
 76 # 生成器表达式
 77 # g = (i for i in range(10)) #几乎不占用内存
 78 # print(g)
 79 # for i in g:
 80 #     print(i)
 81
 82 # g2 = (i for i in range(20) if i%2 == 1)
 83 # for i in g2:
 84 #     print(i)
 85
 86 # g3 = (i*i for i in range(10))
 87 # for i in range(10):
 88 #     print(g3.__next__())
 89
 90 #各种推导式练习
 91 # names = [[‘Tom‘, ‘Billy‘, ‘Jefferson‘, ‘Andrew‘, ‘Wesley‘, ‘Steven‘, ‘Joe‘],
 92 #          [‘Alice‘, ‘Jill‘, ‘Ana‘, ‘Wendy‘, ‘Jennifer‘, ‘Sherry‘, ‘Eva‘]]
 93 # ret = [name for lst in names for name in lst if name.count(‘e‘) == 2]
 94 # print(ret)
 95 # 字典推导式
 96 # mcase = {‘a‘: 10, ‘b‘: 34, ‘A‘: 7, ‘Z‘: 3}
 97 # mcase2 = {k.lower(): mcase.get(k.lower(),0)+mcase.get(k.upper(),0) for k in mcase}
 98 # print(mcase2)
 99 # 集合推导式
100 # sq = {x**2 for x in [1,-1,2]}
101 # print(sq)

原文地址:https://www.cnblogs.com/liuyankui163/p/8185475.html

时间: 2024-11-25 12:50:23

Python之路——迭代器与生成器的相关文章

python之路--迭代器和生成器

迭代: 迭代器协议: 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象 for循环实现迭代的原理: 1.调用__iter__()方法,将后面序列转为

python函数:迭代器和生成器

python函数:迭代器和生成器 迭代器和生成器是函数中的一大重点,务必掌握,何为迭代?何为迭代器? 预习: 处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕(使用生成器) 一.迭代器 for i in 50:     print(i) #运行结果: # Traceback (most recent call last): #   File "G:/python/python代码/八月/day2 迭代器生成器/3迭代器.py", line 8, in &

Python高手之路【九】python基础之迭代器与生成器

迭代器与生成器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁.这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件 特点: 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一

python控制结构、迭代器和生成器(个人笔记)

参考:https://docs.python.org/2.7/reference/compound_stmts.html#whilehttps://www.cnblogs.com/lclq/p/5586198.html (python的运算与表达式)https://www.zhihu.com/question/20829330 (python的迭代器)https://www.cnblogs.com/devin-guwz/p/5738676.html(python入门例题) python中的真假:

1.17 Python基础知识 - 迭代器和生成器初识

可循环迭代的对象称为可迭代对象,迭代器和生成器函数是可迭代对象. 列表解析表达式:可以简单高效处理一个可迭代对象,并生成结果列表 示例代码: [ i ** 2 for i in range(10) ] #输出结果 [0,1,4,9,16,25,36,49,64,81] 生成器表达式:可以简便快捷地返回一个生成器.生成器表达式的语法和列表解析式基本一样,只不过是将[]替换成() 生成器的数据只有在调用时才生成 示例代码: a = ( i ** 2 for i in range(10)) print

python 基础之迭代器与生成器

迭代器和生成器 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大有点是不要求先准备好整个迭代过程中所有的元素.迭代器仅仅在跌带到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁.这个特点使得它特别适合用于遍历一些巨大或者无限的集合. 特点 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容 不能随机访问集合中的

Python成长之路【第五篇】:Python基础之迭代器和生成器

一.递归和迭代 递归就是调用自身 迭代就是每次迭代都是依赖于上次结果 二.什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stopiteration异常,以终止迭代(只能往后走,不能往前退) 2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法) 3.协议是一种约定,可迭代对象实现了迭代器协议,Python的内部工具(如for循环,sum,min,max等函数)都是使用迭代器协议访问对象 三

Python学习之路--迭代器,生成器

迭代器 # 双下方法# print([1].__add__([2]))# print([1]+[2]) # 迭代器# l = [1,2,3]# 索引# 循环 for# for i in l:# i## for k in dic:# pass # list# dic# str# set# tuple# f = open()# range()# enumerate# print(dir([])) #告诉我列表拥有的所有方法# ret = set(dir([]))&set(dir({}))&se

python基础:迭代器、生成器(yield)详细解读

1. 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. 1.1 使用迭代器的优点 对于原生支持随机访问的数据结构(如tuple.list),迭代器和经典for循环的索引访问相比并无优势,反而丢失了索引值(可以使用内建函数enumerate()找回这个索引值).但对于无法随机访问的数据结构(比如set)而言,迭代器是唯一的访问元素的方式. 另外,迭代器的一大优点是不要求事