温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Python中迭代器与生成器怎么使用

发布时间:2022-05-30 09:59:01 来源:亿速云 阅读:179 作者:iii 栏目:开发技术

这篇“Python中迭代器与生成器怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python中迭代器与生成器怎么使用”文章吧。

一、迭代器(foreach)

1、可迭代的对象

内置有__iter__方法的都叫可迭代的对象。

Python内置str、list、tuple、dict、set、file都是可迭代对象。

x = 1.__iter__  # SyntaxError: invalid syntax # 以下都是可迭代的对象 name = 'nick'.__iter__ print(type(name))  # 'method-wrapper'>

2、迭代器对象

执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象。

只有字符串和列表都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的,只能使用迭代器对象。

  • 内置有__iter__方法,执行该方法会拿到迭代器本身。

  • 内置__next__方法,执行该方法会拿到迭代器对象中的一个值。

s = 'hello' iter_s = s.__iter__() print(type(iter_s))  # 'str_iterator'> iter_s为迭代器对象 while True:     try:         print(iter_s.__next__())     except StopIteration:         break #hello

3、迭代器有两个基本的方法:iter() 和 next()。

s = 'hello' iter_s = iter(s) # 创建迭代器对象 print(type(iter_s))  #  iter_s为迭代器对象 while True:     try:         print(next(iter_s)) # 输出迭代器的下一个元素     except StopIteration:         break # hello

4、for迭代器循环

可迭代对象可以直接使用常规for语句进行遍历

for循环称为迭代器循环,in后必须是可迭代的对象。

#str name = 'nick'  for x in name:     print(x) #list for x in [None, 3, 4.5, "foo", lambda: "moo", object, object()]:     print("{0}  ({1})".format(x, type(x))) #dict d = {     '1': 'tasty',     '2': 'the best',     '3 sprouts': 'evil',     '4': 'pretty good' } for sKey in d:     print("{0} are {1}".format(sKey, d[sKey])) #file f = open('32.txt', 'r', encoding='utf-8') for x in f:     print(x) f.close()

5、实现迭代器(__next__和__iter__)

把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。

  • __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。

  • __next__() 方法会返回下一个迭代器对象。

  • StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

创建一个返回数字的迭代器,初始值为 1,逐步递增 1,在 20 次迭代后停止执行:

class MyNumbers:   def __iter__(self):     self.a = 1     return self     def __next__(self):     if self.a <= 20:       x = self.a       self.a += 1       return x     else:       raise StopIteration   myclass = MyNumbers() myiter = iter(myclass)   for x in myiter:   print(x)

1、模拟range

class Range:     def __init__(self, n, stop, step):         self.n = n         self.stop = stop         self.step = step     def __next__(self):         if self.n >= self.stop:             raise StopIteration         x = self.n         self.n += self.step         return x     def __iter__(self):         return self for i in Range(1, 7, 3):     print(i) #1 #4

2、斐波那契数列

class Fib:     def __init__(self):         self._a = 0         self._b = 1     def __iter__(self):         return self     def __next__(self):         self._a, self._b = self._b, self._a + self._b         return self._a f1 = Fib() for i in f1:     if i > 100:         break     print('%s ' % i, end='') # 1 1 2 3 5 8 13 21 34 55 89

二、生成器

1、yield

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

调用一个生成器函数,返回的是一个迭代器对象。

yield后面可以加多个数值(可以是任意类型),但返回的值是元组类型的。

  • 提供一种自定义迭代器的方式

  • yield可以暂停住函数,并提供当前的返回值

import sys def fibonacci(n):  # 函数 - 斐波那契     a, b, counter = 0, 1, 0     while True:         if counter > n:             return         yield a         a, b = b, a + b         counter += 1 f = fibonacci(10)  #f 是一个生成器 print(type(f))  # 'generator'> while True:     try:         print(next(f), end=" ")     except StopIteration:         sys.exit()

yield和return:

  • 相同点:两者都是在函数内部使用,都可以返回值,并且返回值没有类型和个数的限制

  • 不同点:return只能返回一次值;yield可以返回多次值

2、自定义range()方法

def my_range(start, stop, step=1):     while start < stop:         yield start         start += 1 g = my_range(0, 3) print(f"list(g): {list(g)}")

复杂版本:

def range(*args, **kwargs):     if not kwargs:         if len(args) == 1:             count = 0             while count < args[0]:                 yield count                 count += 1         if len(args) == 2:             start, stop = args             while start < stop:                 yield start                 start += 1         if len(args) == 3:             start, stop, step = args             while start < stop:                 yield start                 start += step     else:         step = 1         if len(args) == 1:             start = args[0]         if len(args) == 2:             start, stop = args         for k, v in kwargs.items():             if k not in ['start', 'step', 'stop']:                 raise ('参数名错误')             if k == 'start':                 start = v             elif k == 'stop':                 stop = v             elif k == 'step':                 step = v         while start < stop:             yield start             start += step for i in range(3):     print(i)  # 0,1,2 for i in range(99, 101):     print(i)  # 99,100 for i in range(1, 10, 3):     print(i)  # 1,4,7 for i in range(1, step=2, stop=5):     print(i)  # 1,3 for i in range(1, 10, step=2):     print(i)  # 1,3,5,7,9

3、生成器表达式(i.for .in)

把列表推导式的[]换成()就是生成器表达式 。

优点:比起列表推导式,可以省内存,一次只产生一个值在内存中

t = (i for i in range(10)) print(t)  # <generator object  at 0x00000000026907B0> print(next(t))  # 0 print(next(t))  # 1

举例:

with open('32.txt', 'r', encoding='utf8') as f:     nums = [len(line) for line in f]  # 列表推导式相当于直接给你一筐蛋 print(max(nums))  # 2 with open('32.txt', 'r', encoding='utf8') as f:     nums = (len(line) for line in f)  # 生成器表达式相当于给你一只老母鸡。 print(max(nums))  # ValueError: I/O operation on closed file.

以上就是关于“Python中迭代器与生成器怎么使用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI