Переменная, на которую ссылаются перед ошибкой присваивания в программе простой факторизации?

#python

#python

Вопрос:

Я пишу некоторый код, который должен находить простую факторизацию чисел. Основная функция увеличивается на числа; Я делаю это, потому что хочу использовать код для проведения экспериментов с синхронизацией. Я не против, чтобы это не было сверхэффективным, частью проекта для меня будет сделать его более эффективным самостоятельно. Это также еще не полностью завершено.

 import math
import time

primfac=[]

def primcheck(n):
    for x in xrange(2, int(n**0.5) 1):
        if n % x == 0:
            return False
    return True

def primes(n):
    sieve = [True] * n
    for i in xrange(3,int(n**0.5) 1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i) 1)
    return [2]   [i for i in xrange(3,n,2) if sieve[i]]


def factfind(lsp,n): #finds factors of n among primes
    for i in lsp:
        if n%i==0:
            primfac.append(i)
        else:
            i =1

def simplify(lsp, n):
    x = 1
    for i in lsp:
        x=i*x
    if x != n:
        print "needs exponent, computing"
        for i in lsp:
            y=n/i
            if primcheck(y) == True:
                lsp.append(y)
            else:
                lsp.append(factfind(primes,y))

def primfacfind(n1,n2):
    while n1 <= n2:
        time_start = time.clock()
        if primcheck(n1) == True:
            print "prime"
            time_elapsed = time.clock() - time_start
            print "time:", time_elapsed
            n1 =1
        else:
            n = n1
            print "starting #", n

            factfind(primes(n),n)
            print primfac

            del primfac
            primfac[:] = []
            simplify(primfac, n)

            time_elapsed = time.clock() - time_start
            print "time:", time_elapsed

            n1 =1

primfacfind(6,15)
  

Когда я запускаю код, он выдает это сообщение об ошибке:

 Traceback (most recent call last):
  File "python", line 65, in <module>
  File "python", line 54, in primfacfind
UnboundLocalError: local variable 'primfac' referenced before assignment
  

Чего я не понимаю, потому что я протестировал все функции, кроме simplify функции, и даже тогда единственной новой частью являются строки после print .

Комментарии:

1.Проблема в вашей del primfac строке primefacfind . Это заставляет компилятор назначать primefac переменную как локальную переменную, но поскольку она не создает локальную переменную primefac , вы получаете ошибку времени выполнения UnboundLocalError: local variable 'primfac' referenced before assignment

2. Так вот почему print primfac в else блоке in primefacfind выдает ошибку.

3. Так, например, я думаю, что вместо этого вы хотите достичь primefac.clear() вместо del primefac , потому что последнее приведет к тому, что составитель будет рассматривать primefac как локальную переменную.

4. Извините, в Python 2 вам нужно использовать del primefac[:] вместо primefac.clear() . Итак, в принципе, если вы просто оставите del primfac свою функцию, она должна работать.

Ответ №1:

Функции в python могут обращаться только к переменным, объявленным вне области действия функции, только для чтения без ключевого слова global.

 import math 
import time

primfac=[]

def primcheck(n):
    for x in xrange(2, int(n**0.5) 1):
        if n % x == 0:
            return False
    return True

def primes(n):
    sieve = [True] * n
    for i in xrange(3,int(n**0.5) 1,2):
        if sieve[i]:
            sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i) 1)
    return [2]   [i for i in xrange(3,n,2) if sieve[i]]


def factfind(lsp,n): #finds factors of n among primes
    for i in lsp:
        if n%i==0:
            primfac.append(i)
        else:
            i =1

def simplify(lsp, n):
    x = 1
    for i in lsp:
        x=i*x
    if x != n:
        print "needs exponent, computing"
        for i in lsp:
            y=n/i
            if primcheck(y) == True:
                lsp.append(y)
            else:
                lsp.append(factfind(primes,y))

def primfacfind(n1,n2):
    global primfac
    while n1 <= n2:
        time_start = time.clock()
        if primcheck(n1) == True:
            print "prime"
            time_elapsed = time.clock() - time_start
            print "time:", time_elapsed
            n1 =1
        else:
            n = n1
            print "starting #", n

            factfind(primes(n),n)
            print primfac

            del primfac
            primfac = []
            simplify(primfac, n)

            time_elapsed = time.clock() - time_start
            print "time:", time_elapsed

            n1 =1

primfacfind(6,15)
  

Комментарии:

1. Python может ссылаться на переменные вне функции просто отлично.

2. …но вам нужно ключевое слово global . Код, который я опубликовал, когда в функцию добавляется ключевое слово «global», позволяет избежать ошибки, с которой столкнулся OP.

3. … в отличие от большинства других языков, которые допускают такие вещи без какой-либо специальной обработки. en.wikipedia.org/wiki/Global_variable

4. Хотя добавление глобального ключевого слова устраняет проблему в данном конкретном случае , в общем случае нет необходимости использовать глобальное ключевое слово для ссылки на глобальную переменную в Python. Попробуйте x = 'hi'; def f(): print x; f()

5. Да, но если ваш ответ подразумевает неправильное обобщение, тогда вы должны это исправить.