'complex'对象没有属性'__getitem__'

时间:2013-05-03 09:39:21

标签: python python-3.x

我是python的新手,我正在尝试使用FFT的python实现。我已经有一段时间得到了上面提到的错误。我该怎么办?

import numpy
import cmath

def twiddle(r,s):
    x = (cmath.exp((2*cmath.pi*1j*s)/r))
    return x


def fft(signal):
    n = len(signal)
    if n==1:
        return signal
    else:
        Feven=fft([signal[k] for k in range(0,n,2)])
        Fodd=fft([signal[k] for k in range(1,n,2)])


    for l in range (n/2):
        F1 = Feven[l] + twiddle(n, -l) * Fodd[l]
        F2 = Feven[l] - twiddle(n, -l) * Fodd[l]
        return F1+F2

当我为Feven和Fodd添加印刷语句时,请输入:

print (fft([4.5, 3.4, 4.7, 3.8, 6.7, 8.0, 4.6, 7.8]))

我明白了:

Traceback (most recent call last):
  File "FFT.py", line 41, in <module>
    print (fft([4.5, 3.4, 4.7, 3.8, 6.7, 8.0, 4.6, 7.8]))
  File "FFT.py", line 29, in fft
    Feven=fft([signal[k] for k in range(0,n,2)])
  File "FFT.py", line 34, in fft
   F1 = Feven[l] + twiddler(n, -l) * Fodd[l]
 TypeError: 'complex' object has no attribute '__getitem__'

1 个答案:

答案 0 :(得分:5)

修复错误

问题在于您的行

return F1+F2

这导致fft立即返回(使用复数F1 + F2),实际上它应该返回一个列表。我猜想,你的意思是这样的:

def fft(signal):
    n = len(signal)
    if n==1:
        return signal
    else:
        Feven=fft([signal[k] for k in range(0,n,2)])
        Fodd=fft([signal[k] for k in range(1,n,2)])
    F1 = [Feven[l] + twiddle(n, -l) * Fodd[l] for l in range (n/2)]
    F2 = [Feven[l] - twiddle(n, -l) * Fodd[l] for l in range (n/2)]
    return F1+F2

对您的代码的其他评论

  1. 您可以使用Python's slice notation代替[signal[k] for k in range(0,n,2)]代替signal[0:n:2]。同样地,您可以写[signal[k] for k in range(1,n,2)]而不是signal[1:n:2]

  2. 实际上,由于n是列表signal的长度,因此您可以省略它,因为这是切片的默认行为。所以你实际上可以写:

    Feven = fft(signal[::2])
    Fodd = fft(signal[1::2])
    
  3. else:子句中包含一些“else”代码并且在外部有一些代码是没有意义的。把它全部放在一个或另一个。

  4. 由于Fodd数字总是乘以旋转因子,为什么不这样做一次而不是两次呢?也许是这样的:

    def fft(signal):
        n = len(signal)
        if n == 1:
            return signal
        feven = fft(signal[::2])
        fodd = [twiddle(n, -k) * o for k, o in enumerate(fft(signal[1::2]))]
        f1 = [e + o for e, o in zip(feven, fodd)]
        f2 = [e - o for e, o in zip(feven, fodd)]
        return f1 + f2