迭代器、可迭代对象、生成器、生成器表达式(2) 参考自官方文档

Python官方文档参考链接: 迭代器
Python官方文档参考链接: 生成器
Python官方文档参考链接: 生成器表达式
实验源代码: 下载链接

大多数容器对象都可以使用 for 语句:
请看代码:

print("\n遍历列表:")
for element in [1, 2, 3]:
    print(element)


print("\n遍历元组:")
for element in (1, 2, 3):
    print(element)


print("\n遍历字典:")
for key in {'one':1, 'two':2}:
    print(key)


print("\n遍历字符串:")
for char in "123":
    print(char)


print("\n遍历文本文件:")
for line in open("myfile.txt",encoding='utf-8'):
    print(line, end='')

控制台下的输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代>  & 'D:\Python\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2020.11.367453362\pythonFiles\lib\python\debugpy\launcher' '57985' '--' 'c:\Users\chenxuqi\Desktop\新建文件夹\测试迭代\test_2.py'

遍历列表:
1
2
3

遍历元组:
1
2
3

遍历字典:
one
two

遍历字符串:
1
2
3

遍历文本文件:
Python是一种解释型脚本语言,可以应用于以下领域:

    Web 和 Internet开发
    科学计算和统计
    人工智能
    桌面界面开发
    软件开发
    后端开发
    网络爬虫
PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代> 

这种访问风格清晰、简洁又方便。 迭代器的使用非常普遍并使得 Python 成为一个统一的整体。 在幕后,for 语句会在容器对象上调用 iter()。 该函数返回一个定义了 __next__() 方法的迭代器对象,此方法将逐一访问容器中的元素。 当元素用尽时,__next__() 将引发 StopIteration 异常来通知终止 for 循环。 你可以使用 next() 内置函数来调用 __next__() 方法;这个例子显示了它的运作方式:

Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> s = '林麻子'
>>> it = iter(s)
>>> next(it)
'林'
>>> next(it)
'麻'
>>> next(it)
'子'
>>> next(it)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    next(it)
StopIteration
>>> next(it)
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    next(it)
StopIteration
>>> 
>>> 
>>> 

看过迭代器协议的幕后机制,给你的类添加迭代器行为就很容易了。 定义一个 __iter__() 方法来返回一个带有 __next__() 方法的对象。 如果类已定义了 __next__(),则 __iter__() 可以简单地返回 self:
代码:

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)

    def __iter__(self):
        # self.index = len(self.data) # 这行代码很关键,否则只能迭代完整的一轮
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

rev = Reverse('林麻子')
print(iter(rev))
for char in rev:
    print(char)

for char in rev:
    print(char)

it1 = iter(rev)
print(next(it1))

控制台下的输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代>  & 'D:\Python\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2020.11.367453362\pythonFiles\lib\python\debugpy\launcher' '58276' '--' 'c:\Users\chenxuqi\Desktop\新建文件夹\测试迭代\test_3.py'
<__main__.Reverse object at 0x00000223950163C8>
子
麻
林
Traceback (most recent call last):
  File "c:\Users\chenxuqi\Desktop\新建文件夹\测试迭代\test_3.py", line 26, in <module>
    print(next(it1))
  File "c:\Users\chenxuqi\Desktop\新建文件夹\测试迭代\test_3.py", line 13, in __next__
    raise StopIteration
StopIteration
PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代> 

修改代码,增加一行self.index = len(self.data)修改bug:

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)

    def __iter__(self):
        self.index = len(self.data) # 这行代码很关键,否则只能迭代完整的一轮
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]

rev = Reverse('林麻子')
print(iter(rev))
for char in rev:
    print(char)

for char in rev:
    print(char)

it1 = iter(rev)
print(next(it1))

控制台下的输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代>  & 'D:\Python\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2020.11.367453362\pythonFiles\lib\python\debugpy\launcher' '58296' '--' 'c:\Users\chenxuqi\Desktop\新建文件夹\测试迭代\test_3.py'
<__main__.Reverse object at 0x00000139843D6288>
子
麻
林
子
麻
林
子
PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代> 

生成器
生成器 是一个用于创建迭代器的简单而强大的工具。 它们的写法类似于标准的函数,但当它们要返回数据时会使用 yield 语句。 每次在生成器上调用 next() 时,它会从上次离开的位置恢复执行(它会记住上次执行语句时的所有数据值)。 一个显示如何非常容易地创建生成器的示例如下:

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

for char in reverse("林麻子爱打篮球"):
    print(char)

控制台下输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代>  & 'D:\Python\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2020.11.367453362\pythonFiles\lib\python\debugpy\launcher' '58368' '--' 'c:\Users\chenxuqi\Desktop\新建文件夹\测试迭代\test_4.py'
球
篮
打
爱
子
麻
林
PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代>

可以用生成器来完成的操作同样可以用前一节所描述的基于类的迭代器来完成。 但生成器的写法更为紧凑,因为它会自动创建 __iter__() 和 __next__() 方法。 另一个关键特性在于局部变量和执行状态会在每次调用之间自动保存。 这使得该函数相比使用 self.index 和 self.data 这种实例变量的方式更易编写且更为清晰。 除了会自动创建方法和保存程序状态,当生成器终结时,它们还会自动引发 StopIteration。 这些特性结合在一起,使得创建迭代器能与编写常规函数一样容易。

生成器表达式
某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,但外层为圆括号而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。
查看代码:

temp = sum(i*i for i in range(10))
print(temp)

temp = (i for i in range(0,101))
print(sum(temp))

mySet = set(i for i in range(10))
print(mySet)


myList = list(char for char in "林麻子爱打篮球...")
print(myList)

控制台下的输出:

Windows PowerShell
版权所有 (C) Microsoft Corporation。保留所有权利。

尝试新的跨平台 PowerShell https://aka.ms/pscore6

PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代>  & 'D:\Python\Python37\python.exe' 'c:\Users\chenxuqi\.vscode\extensions\ms-python.python-2020.11.367453362\pythonFiles\lib\python\debugpy\launcher' '58711' '--' 'c:\Users\chenxuqi\Desktop\新建文件夹\测试迭代\test_5.py'
285
5050
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
['林', '麻', '子', '爱', '打', '篮', '球', '.', '.', '.']
PS C:\Users\chenxuqi\Desktop\新建文件夹\测试迭代> 

实验源代码: 下载链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值