Python中可迭代对象与迭代器的区别与用法问题

import requests
from collections import Iterable, Iterator
import json

class WeaherIterator(Iterator):
def init(self, cities):
self.cities = cities
self.index = 0

def getWeather(self, city):
r = requests.get(‘http://wthrcdn.etouch.cn/weather_mini?city=’ + city)
data = r.json()[‘data’][‘forecast’][0]
return ‘%s %s, %s’ % (city,data[‘low’], data[‘high’])


def next(self):
if self.index == len(self.cities):
raise StopIteration
city = self.cities[self.index]
self.index += 1
return self.getWeather(city)



class WeaherIterable(Iterable):
def init(self,cities):
self.cities = cities


def iter(self):
return WeaherIterator(self.cities)

for x in WeaherIterable([‘北京’,‘上海’, ‘长沙’, ‘福州’, ‘广州’, ‘长春’, ‘厦门’]):
print(x)

WeaherIterable 类到底做了什么 没搞懂 我直接用 WeaherIterator 效果是一样的 。为啥要 WeaherIterable 实例传给 WeaherIterator 呢 视频上是说 这样可以延迟显示 有一个显示一个 但是我看直接用 WeaherIterator 也不是一下子显示出来的 也是一个个出来的 。这个 IMOC 上买的视频 有几节课听的一头雾水 求大神指点
Python中可迭代对象与迭代器的区别与用法问题


12 回复

贴代码 为啥显示出来 缩进都没了我 X


Python中可迭代对象与迭代器的区别与用法

简单说:可迭代对象是数据的容器,迭代器是遍历这个容器的工具。

1. 可迭代对象 (Iterable)

  • 任何能用 for 循环遍历的对象
  • 必须实现 __iter__() 方法,返回一个迭代器
  • 常见例子:列表、元组、字符串、字典、集合、文件对象
# 可迭代对象示例
my_list = [1, 2, 3]
my_str = "hello"

# 可以用for循环遍历
for item in my_list:
    print(item)  # 输出: 1 2 3

2. 迭代器 (Iterator)

  • 实现了 __iter__()__next__() 方法的对象
  • __next__() 每次返回下一个元素,没有元素时抛出 StopIteration
  • 迭代器本身也是可迭代的(它的 __iter__() 返回自己)
# 手动使用迭代器
my_list = [1, 2, 3]
iterator = iter(my_list)  # 调用可迭代对象的 __iter__() 获取迭代器

print(next(iterator))  # 输出: 1
print(next(iterator))  # 输出: 2
print(next(iterator))  # 输出: 3
# print(next(iterator))  # 再调用会抛出 StopIteration

3. 关键区别

  • 可迭代对象:可以多次遍历(每次 iter() 返回新的迭代器)
  • 迭代器:只能遍历一次,遍历完后耗尽
# 演示区别
numbers = [1, 2, 3]  # 可迭代对象

# 第一次遍历
for num in numbers:
    print(f"第一次: {num}")

# 可以再次遍历
for num in numbers:
    print(f"第二次: {num}")

# 迭代器示例
iterator = iter(numbers)
list1 = list(iterator)  # [1, 2, 3]
list2 = list(iterator)  # [] 迭代器已耗尽

4. 自定义示例

class CountDown:
    """自定义可迭代对象"""
    def __init__(self, start):
        self.start = start
    
    def __iter__(self):
        return CountDownIterator(self.start)

class CountDownIterator:
    """自定义迭代器"""
    def __init__(self, count):
        self.count = count
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.count <= 0:
            raise StopIteration
        value = self.count
        self.count -= 1
        return value

# 使用
countdown = CountDown(3)
for num in countdown:
    print(num)  # 输出: 3 2 1

5. 实际应用

  • 可迭代对象:当你需要多次遍历数据时
  • 迭代器:处理大数据流、一次性数据、生成器表达式
# 生成器是迭代器的简便写法
def count_down(n):
    while n > 0:
        yield n
        n -= 1

# 生成器函数返回迭代器
for num in count_down(3):
    print(num)  # 输出: 3 2 1

总结:先获取可迭代对象的迭代器,再用迭代器逐个访问元素。

既然是花钱的视频有问题不是应该文卖家吗?

我把__iter__ 也写到 iterator 里面 不是就行了 我看网上也有这种写法 然后 关键是 iterable 这个类不写 直接实例化 iterator 这个类 效果是一模一样的 也就是说 最终起作用的只有) NEXT () 这个方法呀 我绕在这里好久了

好纠结 iterable 没用作用 或者说 我找不到他起作用的点 脑子想的有点疼

Python 里的可迭代对象 iterable 和迭代器 iterator 令人迷惑得厉害 总的来说 迭代器 iterator 是可迭代对象 iterable 的 访问器 迭代器 iterator 原本应该是一个指针,也就说应该具有 iterator->obj::*这种语义,同时迭代器迭代位置还能移动,调用 iterator.next()能获取被迭代对象的下一个元素 iterable 保证能返回一个用于访问其内容的迭代器(或者随机访问器__getitem__),一般 iterable 是某种容器,容器中内容具体如何组织我们不关心,我们只关心怎么取出来然后怎么用,而组织“怎么取”,就是迭代器要做的工作

iterable 不仅包括迭代器关心的那些元素,还包括很多很多其它的东西,比如你可以把整个 v 站视为可迭代的,给它定义一个专门的迭代器对象用来浏览每一个帖子,当你 for 帖子 in v 站的时候这个迭代器帮你遍历所有帖子,但你还可以 v 站.refresh(),v 站.down(),v 站.block(uid)什么的,当你不需要遍历 iterable 的时候,iterable 本身还有很多其它的属性和方法

简单来说,iterable 就是含__iter__方法的,它可不一定是 iterator,interator 是一个具体的对象,比如列表也是 iterable,但不是 iterator。
还有一个理解就是 iterable 就是一个接口,iterator 是一个实现了 iterable 接口的对象。

这些我并不是想不明白 ,只是上面那个 iterable 类 没起作用 有点想不通。


你摆出来的这个例子并没有很好提现 iterable 和对应 iterator 的关系所以你没啥感觉
一个类确实可以同时实现 next 和 iter 两个内置方法,典型的你看 generator 对象就能被获取 iterator,也能调用 next,但对它自己调用 next 还是获取迭代器去访问它内部的元素,意义是完全不一样的

但从逻辑和结构上来说,iterable 是容器,iterator 是访问器,它们的功能就是不一样的。比如现在迭代器已经指向了容器中的某个位置,然后你需要把这个位置信息传递给其它方法去处理,那你肯定希望函数参数传的是一个迭代器,而不需要把原来的整个容器一并传进来;如果还不是很理解,下面这个不很好的例子起码能体现出区别

instance = MyIterable([1,2,3,4,5,6,7,8,9,10])#MyIterable 是随便什么 iterable 类
it = iter(instance)

print( *zip( it,it ) )
print( *zip( instance,instance ) )
print( *zip( *[iter(instance)]*2 ) )


instance =[1,2,3,4]#MyIterable 是随便什么 iterable 类
it = iter(instance)

print( *zip( it,it ) )
print( *zip( instance,instance ) )
print( *zip( *[iter(instance)]*2 ) )

结果
(1, 2) (3, 4)
(1, 1) (2, 2) (3, 3) (4, 4)
(1, 2) (3, 4)

为什么这样呢 不是很懂

原理是因为 NEXT()方法想明白了,但是想不明白的是跟 我上面那个例子的联系。。。

我现在理解的是 iterator 是用来操作 iterable 的 是这样吗? 我最先看到上面那组代码的时候 的印象是 iterablev 那个类是多余的,现在看来 iterator 那个类是干活的 iterable 那个类是容器 怪不得用他来实例话 我这样理解对吗

回到顶部