python生成器笔记

关于python生成器

生成器 generator

定义:能够动态提供数据的可迭代对象。
关于动态的概念:循环一次,计算一次,返回一次。
作用:在循环过程中,按照某种算法推算数据,不需要创建容器存储完整的结果,从而节省内存空间。数据量越大,优势越明显。以上作用也称之为延迟操作或惰性操作,通俗的讲就是在需要的时候才计算结果,而不是一次构建出所有结果。

生成器函数

定义:含有yield语句的函数,返回值为生成器对象
语法
– 创建:
def 函数名():

yield 数据

– 调用:
for 变量名 in 函数名():
语句
说明:
– 调用生成器函数将返回一个生成器对象,不执行函数体。
– yield翻译为”产生”或”生成”。
执行过程:
(1) 调用生成器函数会自动创建迭代器对象。
(2) 在调用迭代器对象的__next__()方法时才执行生成器函数。
(3) 每次执行到yield语句时返回数据,暂时离开
(4) 待下次调用__next__()方法时继续从离开处继续执行。
原理:生成迭代器对象的大致规则如下
– 将yield关键字以前的代码放在next方法中。
– 将yield关键字后面的数据作为next方法的返回值。

下面,我们可以写一些简单的例子,体会生成器函数在运行时的状态。
首先,我们稍微复习再上一篇文章中,通过创建迭代器对象的方法重写range函数。

需求:参照下列代码,自定义MyRange类,实现相同功能
for item in Myrange(n):
print(item)

class MyRange:
    def __init__(self, end=0):
        self.end = end

    def __iter__(self):
        return RangeIterator(self.end)


class RangeIterator:
    def __init__(self, end=None):
        self.end = end
        self.__begin = -1

    def __next__(self):
        self.__begin += 1
        if self.__begin > self.end - 1:
            raise StopIteration
        return self.__begin
#test
for i in MyRange(5):
    print(i)

输出的结果是0,1,2,3,4。
这里我们只是进行简单的重写,并没有再现Range函数中定义起点和步进的功能。
下面,我们通过生成器对自定义函数MyRange进行再重写:

def MyRange(end=0):
    number = 0
    while number < end:
        yield number
        number += 1

#test
for i in MyRange(5):
    print(i)

得到的结果同样是 0,1,2,3,4。
对比上面两段代码,实现相同的功能,代码量和运行时所占用的内存大小也不一样。
在此,稍微穿插迭代器协议。

迭代器协议

迭代器协议指的是对象必须提供一个__next__方法,执行时要么返回迭代中的下一项,要么引起StopIteration异常使得迭代终止。
可迭代对象:实现了迭代器协议的对象。在python中,我们平时使用的for循环就是通过迭代器协议访问对象。

总结

在实际工作应用中,充分利用python的生成器能够减少内存的占用,还能提高代码可读性。希望这篇小笔记能够让读者对生成器有所理解,也希望能够指出我的不足之处。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在信号处理领域,DOA(Direction of Arrival)估计是一项关键技术,主要用于确定多个信号源到达接收阵列的方向。本文将详细探讨三种ESPRIT(Estimation of Signal Parameters via Rotational Invariance Techniques)算法在DOA估计中的实现,以及它们在MATLAB环境中的具体应用。 ESPRIT算法是由Paul Kailath等人于1986年提出的,其核心思想是利用阵列数据的旋转不变性来估计信号源的角度。这种算法相比传统的 MUSIC(Multiple Signal Classification)算法具有较低的计算复杂度,且无需进行特征值分解,因此在实际应用中颇具优势。 1. 普通ESPRIT算法 普通ESPRIT算法分为两个主要步骤:构造等效旋转不变系统和估计角度。通过空间平移(如延时)构建两个子阵列,使得它们之间的关系具有旋转不变性。然后,通过对子阵列数据进行最小二乘拟合,可以得到信号源的角频率估计,进一步转换为DOA估计。 2. 常规ESPRIT算法实现 在描述中提到的`common_esprit_method1.m`和`common_esprit_method2.m`是两种不同的普通ESPRIT算法实现。它们可能在实现细节上略有差异,比如选择子阵列的方式、参数估计的策略等。MATLAB代码通常会包含预处理步骤(如数据归一化)、子阵列构造、旋转不变性矩阵的建立、最小二乘估计等部分。通过运行这两个文件,可以比较它们在估计精度和计算效率上的异同。 3. TLS_ESPRIT算法 TLS(Total Least Squares)ESPRIT是对普通ESPRIT的优化,它考虑了数据噪声的影响,提高了估计的稳健性。在TLS_ESPRIT算法中,不假设数据噪声是高斯白噪声,而是采用总最小二乘准则来拟合数据。这使得算法在噪声环境下表现更优。`TLS_esprit.m`文件应该包含了TLS_ESPRIT算法的完整实现,包括TLS估计的步骤和旋转不变性矩阵的改进处理。 在实际应用中,选择合适的ESPRIT变体取决于系统条件,例如噪声水平、信号质量以及计算资源。通过MATLAB实现,研究者和工程师可以方便地比较不同算法的效果,并根据需要进行调整和优化。同时,这些代码也为教学和学习DOA估计提供了一个直观的平台,有助于深入理解ESPRIT算法的工作原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值