第25天 | 32天学会python, 什么是迭代器?

可迭代对象

迭代器用到两个魔法方法__iter__和__next__

# 有很多可迭代对象: list/tuple/dict/set/str/range/filter/map
# for...in后面加可迭代对象
from collections.abc import Iterable
# 自己仿照list/str等来写一个可迭代对象
class Demo(object):
    count = 0
    def __init__(self,x):
        self.x = x
    def __iter__(self): # 1.只要一个类重写了__iter__方法就是一个可迭代对象
        return self  # 2.返回自己,之后再调用__next__方法,并且__next__调用结束后__iter__会继续不断调用
    def __next__(self):
        self.count += 1
        if self.count <= self.x:
            return self.count - 1
        else:
            raise StopIteration # 3.除非__next__让迭代器停止,才会停止迭代

d = Demo(10)
# isinstance用来判断一个实例对象是否是有指定的类创建出来的
print(isinstance(d, Iterable)) # True

# for...in循环的本质就是调用可迭代对象__iter__方法,获取到这个方法的返回值
# 这个返回值需要是一个对象,然后再调用这个对象__next__方法
for x in d:  # d就是我们自己写了一个range(1,10)
    print(x)
# 0
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9

判断数据是否是可迭代对象

from collections.abc import Iterable
# for...in循环后面需要的是一个可迭代对象
for x in 'hello':  # 字符串是可迭代对象
    print(x)
# for y in 10:  # 数字不是可迭代对象
#     print(y)

a = 'hi'
b = ['婷婷','明明','佳佳','坤坤','琳琳','黎黎','梦凡','瑶瑶']
c = ('yes','good','ok')
d = {1,2,3,4,5,6}
person = {'名字':'张三','年龄':18}
nums = range(0,10)
for 甲 in person:
    print(person[甲])
print('-' * 20)
print(isinstance(a, Iterable))  # True
print(isinstance(b, Iterable))  # True
print(isinstance(c, Iterable))  # True
print(isinstance(d, Iterable))  # True
print(isinstance(person, Iterable))  # True
print(isinstance(nums, Iterable))  # True

手动迭代

# 可迭代对象并不是继承自Iterable 类,而是对象重写了__iter__方法
from collections.abc import Iterable

class Person(object):
    def __init__(self,name):
        self.name = name
        self.count = 0
    def __iter__(self):
        return self  # 类重写了__iter__方法狗需要返回一个可迭代对象,可以直接返回它自己,因为他自己就是一个可迭代对象
        # 返回它自己就会调用它自己的__next__方法,所以我们需要重写__next方法
    def __next__(self):
        if self.count < self.name:
            self.count +=1
            return self.count - 1
        else:
            raise StopIteration # 停止迭代

p = Person(10)

# 手动迭代:
print(p.__iter__().__next__())  # 0
print(p.__iter__().__next__())  # 1
print(p.__iter__().__next__())  # 2
print(p.__iter__().__next__())  # 3
print(p.__iter__().__next__())  # 4

# 等价于上面的代码:
# print(next(iter(p)))  # 0
# print(next(iter(p)))  # 1
# print(next(iter(p)))  # 2
# print(next(iter(p)))  # 3
# print(next(iter(p)))  # 4

我们手动写个range对象

class MyRange(object):
    def __init__(self,x):
        self.x = x
        self.y = 0
    def __iter__(self):
        return self
    def __next__(self):
        if self.y < self.x:
            self.y +=1
            return self.y - 1
        else:
            raise StopIteration

mr = MyRange(10)

for x in mr:
    print(x)  # 1 2 3 4 5 6 7 8 9

# 进阶版:取10-100范围,支持步进
class 取范围(object):
    def __init__(self, 甲, *甲_长度可变参数):
        self.甲 = 甲
        self.乙 = 1
        self.index = 0

        if len(甲_长度可变参数) == 1:
            self.甲 = 甲_长度可变参数[0]
            self.index = 甲
        elif len(甲_长度可变参数) == 2:
            self.甲 = 甲_长度可变参数[0]
            self.乙 = 甲_长度可变参数[1]
            self.index = 甲

    def __iter__(self):
        return self
    def __next__(self):
        if self.index < self.甲 :
            self.index += self.乙
            return self.index - self.乙
        else :
            raise StopIteration

丙 = 取范围(10,55)
for 丁 in 丙:
    print(丁)

迭代器和列表的区别

# 1.列表会申请一块内存空间,用来保存1~1000000 的数字
nums = [i for i in range(1000000)]
print(nums)  # 这100万个数据存在列表中,特别占内存

# 2.迭代器不会开辟内存空间保存数据
for 甲 in range(1000000):
    print(甲) # 随用随取

# 硬件固定的前提下:时间换空间,空间换时间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值