what's the python之可迭代对象、迭代器与生成器(附面试题)

可迭代对象

字符串、列表、元祖、集合、字典都是可迭代的,数字是不可迭代的。(可以用for循环遍历取出内部元素的就是可迭代的)

如何查看一个变量是否为可迭代:

from collections import Iterable

l = [1,2,3,4]
t = (1,2,3,4)
d = {1:2,3:4}
s = {1,2,3,4}                

print(isinstance(l,Iterable))
print(isinstance(t,Iterable))
print(isinstance(d,Iterable))
print(isinstance(s,Iterable))
#结果为True就是可迭代,False就是不可迭代

可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义就是内部实现了__iter__方法,即可迭代对象中封装有__iter__方法。

迭代器

迭代器:用变量调__iter__后就可以生成一个迭代器,迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。

l = [1,2,3,4]
l_iter = l.__iter__()#l_iter只是一个接受的变量
item = l_iter.__next__()#利用迭代器取值
print(item)#1
item = l_iter.__next__()
print(item)#2
item = l_iter.__next__()
print(item)#3
item = l_iter.__next__()
print(item)#4
item = l_iter.__next__()
print(item)#超出限度,报错

上步在最后出现了报错情况,为了使程序不报错,可以在取完了的最后将其终止掉:

l = [1,2,3,4]
l_iter = l.__iter__()
while True:
    try:
        item = l_iter.__next__()
        print(item)
    except StopIteration:
        break

生成器

生成器:(本质就是一个迭代器,不过是由程序员写出来的才叫生成器,内置的就叫迭代器)

  1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行,惰性。

  2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

简易生成器:

import time
def func():
    a = 1
    print(‘现在定义了a变量‘)
    yield a
    b = 2
    print(‘现在又定义了b变量‘)
    yield b

g1 = func()
print(‘g1 : ‘,g1)       #打印g1可以发现g1就是一个生成器
print(‘-‘*20)   #我是华丽的分割线
print(next(g1))
time.sleep(1)   #sleep一秒看清执行过程
print(next(g1))#每print一次next才会出来一个yield的值,不然就挂在上一个yield上不继续执行

生成器有什么好处呢?就是不会一下子在内存中生成太多数据,只有在你要的时候才会给你你要的数据

生成器应用的几个小栗子:

有关衣服订单:

def produce():
    """生产衣服"""
    for i in range(2000000):
        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:         #要一批衣服,比如5件
    print(i)
    num +=1
    if num == 5:
        break

#到这里我们找工厂拿了8件衣服,我一共让我的生产函数(也就是produce生成器函数)生产2000000件衣服。
#剩下的还有很多衣服,我们可以一直拿,也可以放着等想拿的时候再拿

生成器监听文件输入的栗子:

import time

def tail(filename):
    f = open(filename)
    f.seek(0, 2) #从文件末尾算起
    while True:
        line = f.readline()  # 读取文件中新的文本行
        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
    day = 0
    average = 0
    while True:
        term = yield average
        total += term
        day += 1
        average = total/day

g_avg = averager()
next(g_avg)
print(g_avg.send(10))
print(g_avg.send(12))
print(g_avg.send(13))

yield from可以在实行for循环的效果的同时将代码变少:

def gen1():
    for c in ‘AB‘:
        yield c
    for i in range(3):
        yield i

print(list(gen1()))#[‘A‘,‘B‘,1,2,3]

#简化版本
def gen2():
    yield from ‘AB‘
    yield from range(3)

print(list(gen2()))#[‘A‘,‘B‘,1,2,3]

列表推导式和生成器表达式:(这里用一个小故事讲解知识点)

#为了彰显高富帅本质,一口气买了十个茶叶蛋,将他们依次排开并编号,拍照发到朋友圈

egg_list=[‘茶叶蛋%s‘ %i for i in range(10)] #列表解析

#可是这十个茶叶蛋一口气吃不完啊,要吃也就是一个一个吃,那么就吃一个拍一个照吧

eat=(‘茶叶蛋%s‘ %i for i in range(10))#生成器表达式
print(eat)
print(next(eat)) #next本质就是调用__next__
print(eat.__next__())
print(next(eat))

高富帅与茶叶蛋

总结:

1.把列表解析的[]换成()得到的就是生成器表达式

2.列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存

3.Python使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。

附:与生成器相关的面试题:

def demo():
    for i in range(4):
        yield i

g=demo()

g1=(i for i in g)
g2=(i for i in g1)

print(list(g1))#[0,1,2,3]
print(list(g2))#[]

面试题1

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))#[20,21,22,23]

面试题2

what's the python之可迭代对象、迭代器与生成器(附面试题)

原文地址:https://www.cnblogs.com/zhuminghui/p/8206439.html

时间: 2024-10-09 18:00:37

what's the python之可迭代对象、迭代器与生成器(附面试题)的相关文章

11.Python初窥门径(函数名,可迭代对象,迭代器)

Python(函数名,可迭代对象,迭代器) 一.默认参数的坑 # 比较特殊,正常来说临时空间执行结束后应该删除,但在这里不是. def func(a,l=[]): l.append(a) return l print(func(1)) # [1] print(func(2)) # [1,2] print(func(3)) # [1,2,3] 二.函数名的应用 函数名指向的是函数的内存地址,加上()就执行这个函数 def func(args): return args print(func) #

python基础之三大器中迭代器和生成器

迭代器 迭代对象: 在python中,但凡内部含有iter方法的对象,都是可迭代对象. **迭代器: 在python中,内部含有__Iter__方法并且含有__next__方法的对象就是迭代器.** 可迭代对象 str list set dic python中规定,只要具有__ iter__()方法就是可迭代对象 str.__iter__()# list.__iter__()# tuple.__iter__()# dict.__iter__()# set.__iter__() 将可迭代对象转换成

python当中的 可迭代对象 迭代器

学习python有一段时间了,在学习过程中遇到很多难理解的东西,做一下总结,希望能对其他朋友有一些帮助. 完全是个人理解,难免有错,欢迎其他大神朋友们批评指正. 1 迭代 什么是迭代呢??我们可以这样理解,一个容器类型的数据,比如 列表[ ]  .元组 () 和 字典 { }, 我们可以把这样类型的数据放入for temp in [1,2,3] 当中,temp 被一次一次的赋值成为后面容器内数据,然后我们拿到temp进行一些想做的事情.那么for 循环中自动的帮我们把数据一次一次的取出来,可以理

Python itertools 操作迭代对象

Python 的内建模块itertools提供了很多操作迭代对象的方法 参考链接:https://www.liaoxuefeng.com/wiki/1016959663602400/1017783145987360 无限迭代器 count() 返回一个可无限迭代的迭代器,可以用于产生自然数 >>> import itertools >>> natuals = itertools.count(1)#1可以省略不屑,默认从0开始 >>> for n in

【python】 可迭代对象、迭代器、生成器

可迭代对象 iterable 可直接作用于for循环的对象统称为可迭代对象. 有 list. dict.tuple.set.str等数据类型,还有 generator(包括生成器和带yield的generator function).包括了有序和无序对象. 要判断一个对象是否为iterable对象.方法如下: from collections import Iterable isinstance([],Iterable) 迭代器 iterator 迭代,即一些事要重复好多次,就像在循环中做的那样

python之可迭代对象

1. 可迭代对象是什么? 字面意思分析:可以重复的迭代的实实在在的东西 专业角度: 内部含有'__iter__'方法的对象,就是可迭代对象 2. 可迭代对象都有什么? list,dict(keys(),values(),items()),tuple,str,set,range, 文件句柄(待定) 3. 查看内置函数内部有哪些方法 print(dir(str)) 4. 判断一个对象是否是可迭代对象方法 print('__iter__' in dir(str)) # 输出结果 True # 是可迭代

Python学习笔记8(迭代器、生成器、装饰器)

1.列表生成式 要想学习生成器和迭代器,首先得了解另外一个概念,列表生成式. 想要生成一个0~9的列表的时候,首先想到的就是range(0,10) >>>a = range(0,10) >>>print(a) #3.0输出结果 range(0,10) #2.0输出结果 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 在3.0的版本呢当中range只是用来生成一个迭代器了,但是在2.0的版本里可以使用range来快速生成list. 但是想要生成一个[1*1,

Python之装饰器、迭代器和生成器

在学习python的时候,三大“名器”对没有其他语言编程经验的人来说,应该算是一个小难点,本次博客就博主自己对装饰器.迭代器和生成器理解进行解释. 为什么要使用装饰器 什么是装饰器?“装饰”从字面意思来谁就是对特定的建筑物内按照一定的思路和风格进行美化的一种行为,所谓“器”就是工具,对于python来说装饰器就是能够在不修改原始的代码情况下给其添加新的功能,比如一款软件上线之后,我们需要在不修改源代码和不修改被调用的方式的情况下还能为期添加新的功能,在python种就可以用装饰器来实现,同样在写

15.python的for循环与迭代器、生成器

在前面学习讲完while循环之后,现在终于要将for循环这个坑填上了.之所以拖到现在是因为for循环对前面讲过的序列.字典.集合都是有效的,讲完前面的内容再来讲for循环会更加容易上手. 首先,for循环和while循环一样,都是在满足一定条件的时候对其内层的代码进行循环执行.不同的是,while循环判断的是条件,而for判断的是迭代对象. 我们先来看for循环的代码: a = (1, 2, 3, 4, 5) for x in a: print x 我们以序列中的元祖为例,发现其输出了这些,那么