迭代器

Posted ioipchina

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代器相关的知识,希望对你有一定的参考价值。


迭代器:
什么是迭代器:
迭代:更新换代(重复的过程)的过程,每一次迭代都必须基于上一次的结果
迭代器:就是迭代用的特殊指的工具
为什么要用:
迭代器提供了不依赖索引的取值方式

如何使用:
需要使用迭代取值,基本数据类型中可迭代的对象:

列表\字符串\元祖\字典\集合\文件
文件本身就是可迭代器对象

每次迭代都是基于上一次的结果
l = ‘hello‘
n = 0
while n < len(l):
    print(l[n])
    n += 1

  

可迭代对象
只有内置有__iter__方法的都可以叫做可迭代对象
针对有双下划线的开头和双下划线结尾的内置方法都可以讲双下划线+方法名
迭代器对象
可迭代对象执行内置的__iter__后得到就是该迭代器对象
迭代器一定是可迭代对象,而可迭代对象不一定是迭代对象
迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身
迭代器取值的特点:
1.只能往后一次取值,不可以后退
迭代取值的优点:
1.不依赖与索引
2.内存中永远只占一份空间,不会导致内存溢出
缺点:
1.不能够取指定的元素
2.取完之后会报StopIterartion错
示例:
l = [1,2,3,4,5,6,7]
iter_1 = l.__iter__()
print(iter_1.__next__())  # 第一次输出迭代器对象得到 1
print(iter_1.__next__())    # 第二次输出可迭代器对象得到2
print(iter_1.__next__())     # 第三次输出可迭代器对象得到3
print(iter_1.__next__())      # 第四次输出可迭代器对象得到4
print(iter_1.__next__())        # 第五次输出可迭代器对象得到5
print(iter_1.__next__())         # 第六次输出可迭代器对象得到6
print(iter_1.__next__())           # 第七次输出可迭代器对象得到7
# print(iter_1.__next__())            # 第八次输出可迭器代对象得到报错


dict = ‘name‘:‘zhangyaxi‘,‘age‘:‘2‘,‘hobby‘:‘欺负夏哥哥‘
iter_l = dict.__iter__()  # 将可迭代对象字典dict做__iter__操作后得到的结果迭代器对象给iter_l
print(iter_l.__next__())    #   迭代对象取值必须要用___next__
# 第一次得到的值是name
print(iter_l.__next__())
# 第二次得到的值是age
print(iter_l.__next__())
# 第三次得到的值是hobby
print(iter_l.__next__())  # 最后一次输出因为取完了,所已就报错了


以上两个例子我们都得出了取完就报错了,这个问题应该怎么解决?
使用while循环 StooIteration
p = ‘name‘:‘钢铁侠‘,‘name1‘:‘蜘蛛侠‘,‘name2‘:‘雷神‘
iter_p = p.__iter__()
while True:
    try:
        print(iter_p.__next__())
        print(p[iter_p.__next__()])
    except StopIteration:
        print(‘老母猪生不动了!!‘)
        break

  



for循环的内部本质:
for循环的关键的后面的in ,in后面的对象是一个可迭代对象
将in后面的对象使用__iter__转换成迭代器对象
迭代器对象使用__next__可以得到迭代器对象的值
内部出现异常时使用while循环 StopIteration,当__next__报这个错会自动循环

l = ‘name‘:‘孙悟空‘,‘name1‘:‘猪八戒‘

while True:
iter_l = l.__iter__()
    try:
        print(iter_1.__next__())
        print(l[iter_1.__next__()])
    StopIteration:
        braek

# 上下两个例子可以达到相同的功能
for i in l:
    print(l[i])

 

生成器:

用户自定义的迭代器,本质就是迭代器
函数内有yield关键字的函数就是生成器,生成器也是函数的一种表现方式或者说一种使用方法
函数如果使用yield关键字,那么执行函数的时候yield下面的函数体代码则不执行
yield 后面跟的值就是就是需要使用迭代器对象取值__next__方法能得到值
yield的返回值可以是一个值可以是多个值

def func():
    print(‘白龙马‘)    # 第一下次运行输出
    yield ‘哎哎‘    # 函数如果使用yield关键字,那么执行函数的时候yield下面的函数体代码则不执行
    print(‘蹄朝西‘)
    yield ‘嘚嘚‘    #  yield 后面跟的值就是就是需要使用迭代器对象取值__next__方法能得到值
    print(‘背上坐着唐三藏‘)
    yield ‘加加‘
    print(‘后面还跟着三徒弟‘)
    yield ‘哎哟‘
ly = func() # 生成器初始化,将函数变成迭代器
print(ly.__next__())  # 第一次运行输出得到 print(‘白龙马‘)和yield后面的‘哎呦‘然后暂停
print(ly.__next__())  # 第二次运行基于第一次执行的结果在向下面执行 执行完yield 后面的返回值后再次停止
print(ly.__next__())   # 第三次运行基于第二的执行的结果向下运行
print(ly.__next__())
print(ly.__next__())  # 因为已经在上一步完毕,这一步已经没有可以执行的代码了所以会报错 StopIteration的错误信息


l = ‘name‘:‘孙悟空‘,‘name1‘:‘猪八戒‘

while True:
iter_l = l.__iter__()
    try:
        print(iter_1.__next__())
        print(l[iter_1.__next__()])
    StopIteration:
        braek

# 上下两个例子可以达到相同的功能
for i in l:
    print(l[i])
yield 支持外界传参
yield 可以提供一种定义生成器的方式
会将函数的运行状态暂停
可以返回值
yield 与return的差别:
相同点:都可以有返回值,并且都可以返回多个值
不同点:
yield可以返回次值,而return只能返回一次值
yield还可以外部传入值

示例:
def dog(name):
    peint(‘%s可以开始‘%name)
    while True:
        food = yield # 当函数内有yield关键字的时候,调用该函数不会执行函数体代码
        print(‘%s吃了%s‘%name,food)
de = gog(‘德玛西亚‘)  #是将函数变成生成器
de.__next__()   # 只有代码运行至yield才可以赋值
de.send(‘狗不理包子‘) # 给yield左边的变量传参

  


生成器表达式:
res = (i for i in range(1,10,2) if i != 4) #生成器表达式
print(res) # 运行结果为 <generator object <genexpr> at 0x000001F9FEF83BA0>
print(res.__next__()) # 生成器不会主动运行代码 必须通过__next__来触发才能执行


常用内置函数
abs()求绝对值
print(abs(-11))
#得到的值为11
all(),any()
l = [1,0,1]
print(all(l)) # 只要有一位False,就返回Fales
print(any(l)) # 只要有一位True ,就返回True

locals(),globals()
def innter():
username = ‘我是局部名称空间里面的username‘
print(locals()) # 当前语句在哪个位置,就会返回当前名称空间内存储的所有名字
print(globals()) # 无论在哪 查看的都是全局名称空间

index()索引
bin(),oct(),hex(),
print(bin(19)) # 0b10011 10进制转2进制
print(oct(19)) # 0o23 10进制转8进制
print(hex(19)) # 0x13 10进制转16进制
print(int(0b10011)) # 19 2进制转10进制

bool()
print(bool(0)) # 结果为False
print(bool(1)) # 结果为True

bytes()
s = ‘hello‘
print(s.encode(‘utf-8‘))
# 上下结果一样
print(bytes(s,encoding=‘utf-8‘))

collable() 判断对象是否可以调用

l = [1,2,3,4]
def index():
pass
print(callable(1)) # 判断对象是否可调用
print(callable(index)) # 判断对象是否可调用

chr ord
print(chr(90)) # 将数字转换成ascii码
print(ord(Z)) # 将字符按照ASCII表转成对应的数字


dir 获取当前对象名称空间里面的名字
l = [1,2,3,4,5]
print(dir(l))

divmod 分页器
print(divmod(100,9))

total_num,more = divmod(100,9)
if more:
total_num +=1
print(‘总页数‘,total_num)

enumerate 枚举

l = [‘a‘,‘b‘]
for i,j in enumerate(l,1)
print(i,j) # 1 a 2 b

eval exec

s = """
print(‘妹妹卓坐船头‘)
x = 1
y = 2
print(x + y)
"""

eval 不支持逻辑代码,只支持一些简单的python代码
exec 可以支持逻辑代码

format 三种使用方法
占位
index 索引
name 指名道姓的占位

help() 可以查看函数的备注
def login():
"""
一起喝酒
:return
"""
print(help(login))


isinstance 后面统一改方法判断对象是否属于某个数据类型
n = 1
print(type(n))
print(isinstance(n,list)) # 判断为False

pow() 次方
print(pow(2,3)) #结果为8 2的3次方

round() 四舍五入

print(round(3.4))

以上是关于迭代器的主要内容,如果未能解决你的问题,请参考以下文章

五 迭代器生成器

STL迭代器相关的输出迭代器

课时10:迭代器迭代器失效分析

C++迭代器 iterator

C++迭代器 iterator

25Python之迭代器