Python类型错误:“NoneType”对象不是可订阅的

时间:2021-06-22 16:57:23

I am trying to write a function that performs backsubstitution on a matrix already in echelon form, but every time I try to access an index of my matrix I get - TypeError: 'NoneType' object is not subscriptable. I've been working with this for hours now and am getting really frustrated, although I am probably overlooking an obvious detail. Here is my code:

我正在尝试编写一个函数,它对已经处于阶梯形形式的矩阵执行逆向替换,但是每次我试图访问矩阵的索引时,我都会得到- TypeError: 'NoneType'对象不是可订阅的。我已经用它工作了几个小时了,我真的很沮丧,尽管我可能忽略了一个明显的细节。这是我的代码:

def backsubstitution(B):
    """
    return the reduced row echelon form matrix of B
    """
    G = B.copy()
    m, n = np.shape(G)
    pivot = 0
    # To start, let i = 0
    i = 0
    # If row i is all zeros, or if i exceeds the number of rows in A, stop
    while(i != m):
        # If row i has a nonzero pivot value, divide row i by its pivot value to
        # create a 1 in the pivot position
        # First, find the pivot position
        pivPos = 0
        while(G[i][pivPos] == 0.0):
            pivPos += 1
            if(pivPos == n-1 and G[i][pivPos] == 0.0):
                return G
        # Now divide row i by its pivot value if the pivot is not already 1
        if(G[i][pivPos] != 1):
            pivot = G[i][pivPos]
            for k in range(n):
                if(G[i][k] == 0.0):
                    G[i][k] == 0.0
                else:
                    G[i][k] = (G[i][k] / pivot)
        # Use row reduction operations to create zeros in all positions above the
        # pivot
        if(i != 0):
            for l in range(i):
                G = rowReduce(G, i, i-1, pivPos)         
        # Let i = i + 1
        i += 1
    return G

If anyone can help, I would be immensely grateful.

如果有人能帮忙,我将万分感激。

Edit: The hashed comments are the steps for the backsubstitution algorithm as given by my professor.

编辑:散列注释是我的教授给出的反替换算法的步骤。

2nd Edit: rowReduce is a function provided by the professor

编辑:rowReduce是由教授提供的函数

3rd Edit: Here's rowReduce:

3日编辑:rowReduce:

def relError(a, b):
    """
    compute the relative error of a and b
    """
    with warnings.catch_warnings():
        warnings.simplefilter("error")
        try:
            return np.abs(a-b)/np.max(np.abs(np.array([a, b])))
        except:
            return 0.0

def rowReduce(A, i, j, pivot):
    """
    reduce row j using row i with pivot pivot, in matrix A
    operates on A in place
    """
    factor = A[j][pivot] / A[i][pivot]
    for k in range(len(A[j])):
        # we allow an accumulation of error 100 times larger than a single computation
        # this is crude but works for computations without a large dynamic range
        if relError(A[j][k], factor * A[i][k]) < 100 * np.finfo('float').resolution:
            A[j][k] = 0.0
        else:
            A[j][k] = A[j][k] - factor * A[i][k]

I am calling the function on a matrix M already in echelon form : backSub = backsubstitution(M)

我调用矩阵M上的函数已经是阶梯形了,backSub = back置换(M)

1 个解决方案

#1


2  

Notice that the doc string of rowReduce says it "operates in place". That means it changes the array you pass it, rather than giving you a new one back. If this wasn't explicitly documented, another big indicator is that it lacks any return statement.

注意,rowReduce的doc字符串表示它“在适当的位置上运行”。这意味着它会改变你传递给它的数组,而不是给你一个新的数组。如果没有明确地记录这一点,另一个重要的指标是它没有任何返回语句。

That means that this line:

这意味着这条线:

G = rowReduce(G, i, i-1, pivPos)

should just be:

应该是:

rowReduce(G, i, i-1, pivPos)

Since rowReduce doesn't return a new array (or indeed explicitly return at all), its return value will be None. When you reassign that result back to G, it will be None when you go back to the top of the loop and try to do this:

由于rowReduce不返回一个新的数组(或者实际上完全显式地返回),它的返回值将为None。当您将结果重新分配给G时,当您回到循环的顶部并尝试这样做时,结果将为None:

G[i][pivPos]

Which will give you the TypeError you see.

它会给你你看到的类型错误。

#1


2  

Notice that the doc string of rowReduce says it "operates in place". That means it changes the array you pass it, rather than giving you a new one back. If this wasn't explicitly documented, another big indicator is that it lacks any return statement.

注意,rowReduce的doc字符串表示它“在适当的位置上运行”。这意味着它会改变你传递给它的数组,而不是给你一个新的数组。如果没有明确地记录这一点,另一个重要的指标是它没有任何返回语句。

That means that this line:

这意味着这条线:

G = rowReduce(G, i, i-1, pivPos)

should just be:

应该是:

rowReduce(G, i, i-1, pivPos)

Since rowReduce doesn't return a new array (or indeed explicitly return at all), its return value will be None. When you reassign that result back to G, it will be None when you go back to the top of the loop and try to do this:

由于rowReduce不返回一个新的数组(或者实际上完全显式地返回),它的返回值将为None。当您将结果重新分配给G时,当您回到循环的顶部并尝试这样做时,结果将为None:

G[i][pivPos]

Which will give you the TypeError you see.

它会给你你看到的类型错误。