如何将递归转换为循环以避免最大递归错误

时间:2014-03-24 23:21:16

标签: python recursion iteration

以下是我程序中的一段代码:

def get_data(self):
    self.position = self.hfile.tell()/self.sizeof_data


    try:
        self.iq = scipy.fromfile(self.hfile, dtype=self.datatype, count=self.block_length)


    except MemoryError:
        print "End of File"
    else:
        self.iq_fft = self.dofft(self.iq)
    x = self.iq_fft

        maximum = np.argmax(x)
        average = np.mean(x)

    print "\nAvage Value: ", average 

        #set up Get Data loop
        loops = self.files/self.block_length
        self.counter += 1
        count = self.counter
        count += 1
        print "\nCOUNT: ", count
        #print "\nloop: ", loops

    if count == loop:
        raise SystemExit #Exits program gracefully
    else:   
        self.get_data()



def dofft(self, iq):
    N = len(iq)

    iq_fft = scipy.fftpack.fftshift(scipy.fft(iq))       # fft and shift axis


    iq_fft = scipy.log10(abs((iq_fft))) # convert to decibels, adjust power
    # adding 1e-15 (-300 dB) to protect against value errors if an item in iq_fft is 0

    return iq_fft

除非循环大于989,否则效果很好,然后整个事情就会爆炸。我已经看到一些关于如何在Python递归中限制为999的讨论,所以我知道这是问题所在,但我怎样才能重写循环以避免错误?循环有可能变得非常大,所以我不认为使用setrecursionlimit()函数是一个好主意。

4 个答案:

答案 0 :(得分:1)

要确切地说出你要完成的是什么有点难,但看起来你需要像

这样的东西
import scipy as sp
import scipy.fftpack as sf

def db_fft(block):
    res = sp.fft(block)         # compute FFT
    res = sf.fftshift(res)      # shift axis
    res = sp.log10(abs((res)))  # convert to db, adjust power
    return res

class BlockFFT:
    def __init__(self, fname, dtype=sp.float64, blocksize=256*256):
        self.hfile     = open(fname, "rb")
        self.dtype     = dtype      # data type
        self.blocksize = blocksize  # number of items per step

    def next(self):
        try:
            block = scipy.fromfile(self.hfile, dtype=self.dtype, count=self.blocksize)
            fft   = db_fft(block)
            return fft, sp.argmax(fft), sp.mean(fft)
        except MemoryError:
            self.hfile.close()
            raise StopIteration()

def main():
    for fft, max_, avg_ in BlockFFT("myfile.dat"):
        # now do something with it
        pass

if __name__=="__main__":
    main()

答案 1 :(得分:1)

我不明白为什么你把它写成递归的时候它显然是一个迭代过程(按照我的理解逐块读取文件)。

def get_data(self):
    for count in range(self.files/self.block_length):
        self.position = self.hfile.tell()/self.sizeof_data

        try:
            self.iq = scipy.fromfile(self.hfile, dtype=self.datatype, count=self.block_length)
        except MemoryError:
            print "End of File"

        self.iq_fft = self.dofft(self.iq)
        x = self.iq_fft

        maximum = np.argmax(x)
        average = np.mean(x)

        print "\nAverage Value: ", average 

        self.counter += 1
        print "\nCOUNT: ", count
    raise SystemExit

答案 2 :(得分:0)

也许这个:

while count != loop
    #run whatever is in get data
else
    raise SystemExit

但是,如果您提供了更多信息,我可能会选择for循环。

答案 3 :(得分:-1)

获取函数以返回绑定函数,然后运行它直到没有返回任何函数。 您可以使用functools中的partial绑定函数。

from functools import partial
def yourfunc(test):
    # code
    if answer:
        return answer
    return partial(yourfunc,boundvariable)