Python迭代器与生成器研究记录

Python迭代器与生成器研究记录

前言

迭代器肯定是可迭代对象,但是可迭代对象不一定是迭代器,生成器一定是迭代器,但是迭代器不一定是生成器
生成器是特殊的迭代器,所以生成器一定是迭代器,迭代器一定是可迭代对象
我们平常接触最多的对象中,字符串,字典,列表,集合,元组和open打开的文件对象等都是可迭代的对象因为他们都有__iter__()方法,可以遍历
需要注意的是,我们平常接触最多的对象中,字符串,字典,列表,集合,元组等都不是迭代器因为他们都没有__next__()方法,但是open打开的文件对象却是一个迭代器对象

可迭代对象

1.只要内部有__iter__()方法的对象就是可迭代对象如 字符串,字典,列表集合,元组,包括open打开的文件对象也都是可迭代对象
2.或者可以这样说,只要可以转换成迭代器的对象就是可迭代对象

这些都是可迭代对象

test_list = [1, 3, 4, 7]
test_list.__iter__()
test_str = "test_str"
test_str.__iter__()
test_dict = {
   "1":12}
test_dict.__iter__()
test_set = {
   "1", "4", "898"}
test_set.__iter__()
with open("file_path", "r") as file_obj:
    file_obj.__iter__()

可迭代对象调用__iter__()方法会返回一个迭代器,代码如下

test_list = [1, 3, 4, 7]
print(test_list.__iter__())
print(type(test_list.__iter__()))
# 可迭代对象调用__iter__()方法返回的就是一个迭代器
# <list_iterator object at 0x000001CEB3AD5518>
# <class 'list_iterator'>

迭代器

迭代器就是有__iter__()方法和__next()__方法的对象,所以迭代器肯定是可迭代对象,但是可迭代对象不一定是迭代器
迭代器对象调用__next__()方法每次会拿到迭代器里面的一个值并返回,直到全部拿完会报错StopIteration
迭代器对象调用__iter__()方法返回的是迭代器本身(和没调用一样),可迭代但是非迭代器的对象调用__iter__()方法也是返回的是基于这个对象的迭代器

需要注意的是,我们平常接触最多的对象中,字符串,字典,列表,集合,元组等都不是迭代器因为他们都没有__next__()方法,但是open打开的文件对象却是一个迭代器对象

# 迭代器的一个特征就是有__next__()方法
test_list = [1, 3, 4, 7]
# 可迭代对象调用__iter__()方法返回的就是一个迭代器
list_iterator_obj = test_list.__iter__()

# 迭代器调用_next__()方法每次就会拿出这个迭代器里面的一个值,直到全部拿完会报错
for i in range(5):
    print(list_iterator_obj.__next__())


# 1
# 3
# 4
# 7
# Traceback (most recent call last):
#   File "C:/Users/xxx/Desktop/python_test_dir/test_4.py", line 10, in <module>
#     print(list_iterator_obj.__next__())
# StopIteration

迭代器对象调用__iter__()方法返回的是他自己,和没调用一样

# 迭代器的特征就是有__next__()方法
test_list = [1, 3, 4, 7]
# 可迭代对象调用__iter__()方法返回的就是一个迭代器
list_iterator_obj = test_list.__iter__()

# 迭代器对象调用__iter__()方法返回的是他自己,和没调用一样
list_iterator_obj2 = list_iterator_obj.__iter__()
print(list_iterator_obj2 is list_iterator_obj)      # True


print(list_iterator_obj.__next__())     # 1
print(list_iterator_obj.__next__())     # 3
# 注意这里会返回此迭代器对象直接理解为是 list_iterator_obj = list_iterator_obj (因为是返回自己,所以里面剩余的值状态也是一样的)
list_iterator_obj = list_iterator_obj.__iter__()
print(list_iterator_obj.__next__())     # 4
print(list_iterator_obj.__next__())     # 7


for 循环遍历的本质可以理解成
1,每次调用此对象的__iter__()方法返回这个对象的迭代器版本
2,调用第一步返回的此迭代器版本的__next__()方法拿出里面的一个值
3,循环执行第二步直到所有元素拿完for 循环捕获结束时抛出的StopIteration异常并结束

生成器

生成器可以理解为自己定义的一个迭代器,可以自定义一个生成器,生成器定义有两种方法
1.函数yield关键字返回,含有yield关键字的函数会返回一个生成器对象,对此对象调用__next__()方法会执行此函数对应的yield关键字之前的代码并且返回yield关键字字后的返回值然后截止,下次调用__next__()方法又可以在上次的基础上继续执行
2.生成器表达式(我们以为的"元组推导式"就是生成器表达式,需要注意元组因为是不可变的所以元组没有推导式,类似元组推导式的形式其实是生成器表达式)

函数yield关键字生成器

def test():
    print("第一次执行")
    yield 1
    print("第二次执行")
    yield 2
    print("第三次执行")
    yield 3
    print("第四次执行")
    yield 4
    print("最后一次执行")


# test函数返回一个生成器对象
generator_obj = test()

print(generator_obj)  # <generator object test at 0x000001B393528C00>

print(generator_obj.__next__())
# 第一次执行
# 1
print(generator_obj.__next__())
# 第二次执行
# 2
print(generator_obj.__next__())
# 第三次执行
# 3
print(generator_obj.__next__())
# 第四次执行
# 4
print(generator_obj.__next__())
# 最后一次执行
# Traceback (most recent call last):
#   File "C:/Users/xxx/Desktop/python_test_dir/test_4.py", line 51, in <module>
#     print(generator_obj.__next__())
# StopIteration

生成器表达式

test_list = [10, 20, 30, 40]
generator_obj = (i for i in test_list)
print(generator_obj) # <generator object <genexpr> at 0x0000029852C98C00>
print(generator_obj.__next__())  # 10
print(generator_obj.__next__())  # 20
print(generator_obj.__next__())  # 30
print(generator_obj.__next__())  # 40
```bash
# obj.__next__()方法 等价于next(obj)
# obj.__iter__()方法 等价于iter(obj)

test_list = [10, 20, 30, 40]
generator_obj = (i for i in test_list)
print(generator_obj) # <generator object <genexpr> at 0x0000029852C98C00>
print(generator_obj.__next__())  # 10
print(generator_obj.__iter__())  # <generator object <genexpr> at 0x0000029852C98C00>
print(next(generator_obj))  # 20
print(iter(generator_obj))  # <generator object <genexpr> at 0x0000029852C98C00>

相关推荐

  1. Python生成器研究记录

    2023-12-12 23:16:03       34 阅读
  2. Python中的生成器

    2023-12-12 23:16:03       12 阅读
  3. Python

    2023-12-12 23:16:03       14 阅读
  4. Python

    2023-12-12 23:16:03       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-12 23:16:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-12 23:16:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-12 23:16:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-12 23:16:03       18 阅读

热门阅读

  1. Optional

    2023-12-12 23:16:03       38 阅读
  2. IT运维产业在大数据驱动变革下的应用建议

    2023-12-12 23:16:03       41 阅读
  3. HR如何筛选简历?

    2023-12-12 23:16:03       37 阅读
  4. SQL命令---修改字段名

    2023-12-12 23:16:03       36 阅读
  5. 数据冗余(data redundant)现象介绍

    2023-12-12 23:16:03       33 阅读