Python15 理解Python迭代器

图片

1.Python中的迭代器

在Python中,迭代器是一种允许程序员遍历一个容器(特别是列表、元组、字典等集合类型)的对象,而不需要了解容器的内部结构。迭代器提供了一个统一的方法来逐一访问容器中的元素,这种机制称为迭代。

迭代器的核心概念:迭代器基于两个基本方法来完成其功能:

  1. __iter__()

    • 这个方法返回迭代器对象本身。这是使用forin语句时所必需的,因为Python的迭代协议要求一个对象要么有__iter__()方法,要么有__getitem__()方法。

  2. __next__()

    • 这个方法返回容器的下一个元素。当没有更多元素可供返回时,它应该抛出一个StopIteration异常,用来通知迭代循环结束。

迭代器的使用:

在Python中,直接作用于for循环的对象统称为可迭代对象(Iterable),任何实现了__iter__()__next__()方法的对象都是迭代器(iterator)。所有的Iterable均可以通过内置函数iter()来转变为Iteratoriter()函数用于获取迭代器,而next()函数用于逐一访问迭代器的元素。

2.迭代器的使用

① 使用方法

使用自定义迭代器:

class MyIterator:
    def __init__(self, data):
        self.data = data
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.data):
            raise StopIteration
        value = self.data[self.index]
        self.index += 1
        return value

# 使用自定义的迭代器
my_iter = MyIterator([1, 2, 3, 4, 5])

# 在for循环中使用迭代器
for item in my_iter:
    print(item)

图片

next()需要传入可迭代对象:

L=[1,2,3]  # L是一个可迭代对象,而不是一个迭代器
squares=[x**2 for x in L]
squares  # 同理,squares是一个可迭代对象
next(L)  # 将会抛出错误:TypeError: 'list' object is not an iterator

图片

my_list = [1, 2, 3, 4]
my_iter = iter(my_list)  # 创建迭代器对象

print(next(my_iter))  # 输出 1
print(next(my_iter))  # 输出 2
print(next(my_iter))  # 输出 3
print(next(my_iter))  # 输出 4
print(next(my_iter))  # 抛出StopIteration异常,迭代结束

图片

import sys
list=[1,2,3,4]
it=iter(list)
while True:
    try:
        print(next(it))
    except StopIteration:
        sys.exit()

图片

需要将可迭代对象通过iter()转换成一个迭代器:

ls=[1,2,3,4]
it=iter(ls)  # 列表转换为一个迭代器
for x in it:
    print(x,end=" ")

图片

② 使用生成器生成迭代器

生成器是一种特殊类型的迭代器,它们可以被用来按需生成数据,而不是一次性地将数据加载到内存中。这样做可以提高程序的内存效率,特别是当处理大量数据时。下面的代码使用生成器(generator)创建一个逐个生成平方数的迭代器。

# 生成器
def gensquares(N):
    for i in range(N):
        yield i**2
for item in gensquares(5):
    print(item)

图片

使用普通函数创建一个逐个生成平方数的迭代器:

#使用普通函数
def gensquares(N):
    res=[]
    for i in range(N):
        res.append(i**2)
    return res
for i in gensquares(5):
    print(i)

图片

③ 迭代器协议

Python使用迭代器协议让for循环变得更加通用,许多Python的内置函数,如summinmaxmap等,都可以接受任何迭代器作为输入。这些函数使用迭代器协议来访问传入对象中的元素。例如sum函数可以接受任何迭代器,并计算其中元素的总和。

迭代器协议是Python的强大特性之一,它允许内置函数和控制结构以统一的方式处理多种类型的数据集合。通过支持这个协议,生成器成为了处理序列数据的灵活和强大工具,尤其是在数据量大或数据产生代价高的场景中。

# 使用生成器表达式创建一个生成器
numbers = (x * x for x in range(5))  # 生成 0, 1, 4, 9, 16
# 使用sum函数计算这些值的和
total = sum(numbers)
print(total)  # 输出 30
④ 生成器的惰性求值(Lazy Evaluation)

生成器的惰性求值(Lazy Evaluation)是指在真正需要数据之前不进行任何计算或数据生成的编程技术。这种策略允许代码只在结果真正被需要时才执行运算,从而节省资源和提高程序的效率。

从一个文本文件input.txt中按行读取内容,并且仅当行中包含指定关键词‘Hello’时,逐行返回这些匹配的行(10行中提取了6行含有关键词的文本行)。这种方式是处理大文件的有效方法,因为它允许按需读取数据,而不必一次性将整个文件加载到内存中。

图片

import chardet  # 自动检测文件编码的库

def detect_encoding(file_path):  # 定义一个检测文件编码的函数
    with open(file_path, 'rb') as f:
        rawdata = f.read()
    return chardet.detect(rawdata)['encoding']

def search_in_file(path, keyword):
    try:
        # 检测文件编码
        encoding = detect_encoding(path)
        # 使用检测到的编码打开文件
        with open(path, 'r', encoding=encoding) as file:
            for line_number, line in enumerate(file, 1):  # 遍历文件的每一行,使用 enumerate 函数获取行号,并检查是否存在关键字
                if keyword in line:
                    yield line_number, line
    except FileNotFoundError:
        print("文件未找到,请检查文件路径。")
    except Exception as e:
        print(f"读取文件时发生错误:{e}")

# 示例
filename = r'F:\桌面\python100\input.txt'
keyword = "Hello"
for line_number, matching_line in search_in_file(filename, keyword):
    print(f"第 {line_number} 行: {matching_line}")

图片


以上内容总结自网络,如有帮助欢迎转发,我们下次再见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值