Локальная переменная, на которую ссылаются перед присваиванием - ошибка - PullRequest
1 голос
/ 12 февраля 2020

Эта функция должна добавлять 1 к числу, указанному в форме списка. Если список равен [1, 2, 3], то эта функция должна возвращать [1, 2, 4], поскольку 123 + 1 == 124.

Ниже приведена рассматриваемая функция:

def plusOne(self, A):
    val = 1;
    for i in range(len(A)-1,0,-1):
        val = val + A[i]
        borrow = int(val/10)
        if borrow == 0:
            A[i] = val
            break;
        else:
            A[i] = val%10
            val = borrow
    A = [borrow] + A
    while A[0]==0:
        del A[0]
    return A

Сообщение об ошибке:

Traceback (most recent call last):
  File "main.py", line 225, in 
    Z = obj.plusOne(A)
  File "/tmp/judge/solution.py", line 8, in plusOne
    A = [borrow] + A
UnboundLocalError: local variable 'borrow' referenced before assignment

И, что удивительно, приведенный ниже код работает без ошибок:

class Solution:
    # @param A : list of integers
    # @return a list of integers
    def plusOne(self, A):
        val = 1;
        for i in range(len(A),0,-1):
            val = val + A[i-1]
            borrow = int(val/10)
            if borrow == 0:
                A[i-1] = val
                break;
            else:
                A[i-1] = val%10
                val = borrow
        A = [borrow] + A
        while A[0]==0:
            del A[0]
        return A

Я до сих пор не понимаю, что если инициализация переменной заимствования непосредственно внутри l oop вызывает ошибку, то приведенный выше фрагмент тоже должен выдавать ошибку, верно?

Ответы [ 3 ]

3 голосов
/ 12 февраля 2020

заем объявляется / инициализируется внутри for l oop.

for i in range(len(A)-1,0,-1):

Что если len (A) равен 1, тогда не будет никакого диапазона до l oop и займа никогда не попадет в область видимости, следовательно ошибка.

0 голосов
/ 12 февраля 2020

Есть несколько проблем с вашим кодом. В большинстве случаев он работает как задумано. Позвольте мне предложить несколько улучшений и указать на проблемы.

Прежде всего, в вашем коде две точки с запятой, они не нужны в Python. (line 2) val = 1; и (line 8) break;

Во-вторых, когда списки отправляются в методы и функции, они отправляются как ссылки, и поэтому изменения внутри этих методов будут применяться к исходному списку.

В-третьих, разрыв внутри al oop обычно показывает неправильный выбор и планирование.

В-четвертых, если plusOne не является частью класса, тогда нет необходимости в self в качестве его параметров (если он является частью класса, затем оставьте его там и вызовите с помощью self.plusOne(..) при вызове.

Вот как я бы это сделал для другой точки зрения:

def plusOne(self, lst):
    if len(lst) > 0:
        # Initial value to increase by
        val = 1
        # Initialization of list index to last element.
        i = -1
        # Calculate the number after addition, calculate the borrow and replace in the list.
        num = val + lst[i]
        borrow = num // 10
        lst[i] = num % 10
        # While there is any borrow and the list didn't read the first element.
        while borrow != 0 and i > len(lst)*-1:
            # Update the borrow to new value.
            val = borrow
            # Decrease the index.
            i -= 1
            # Calculate the number after addition, calculate the borrow and replace in the list.
            num = val + lst[i]
            borrow = num // 10
            lst[i] = num % 10

        # Check if borrow remaining after index out of range.
        if borrow != 0:
            # Insert borrow before the first element.
            lst.insert(0, borrow)
        # Remove leading zeros.
        while lst[0] == 0:
            del lst[0]


def main():
    lst = [1, 2, 9]
    plusOne('', lst)
    print(lst)


if __name__ == '__main__':
    main()
0 голосов
/ 12 февраля 2020

Проблема, с которой вы сталкиваетесь, является классической c проблемой scoping .

Переменная borrow не определена перед for l oop и кодом пытается получить к нему доступ после l oop.

Если len(A) > 1, ваш код будет работать идеально, потому что в этом случае borrow определен в l oop и l oop Выполнено.

Но, если len(A) <= 1, в таком случае код напрямую пытается получить доступ к переменной borrow, которая никогда не была определена ранее.

В таком сценарии ios Лучше всего определять переменные со значением по умолчанию. В этом случае borrow = 0 будет правильным значением, если вы определите его до for l oop.

Надеюсь, это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...