如果在这种情况下使用g,为什么会给我错误?

时间:2019-01-10 06:43:07

标签: python

我正在尝试使用以下代码打印质数:

import math    

b=[]
for num in range(2,1000):
    if num>1:
        if all(num%g!=0 for g in range(2,int(math.sqrt(num))+1)):
            print(g)
            b.append(num)
print(b)

我的问题是当我尝试打印g时为什么会显示错误NameError: name 'g' is not defined。为什么我不能打印g

2 个答案:

答案 0 :(得分:0)

因为之后

if all(num%g!=0 for g in range(2,int(math.sqrt(num))+1)):

执行,g已从本地帧中删除,未定义为本地变量。您可以将上面的代码重写为for循环并在其中循环打印g,这很清楚为什么不能调用print(g):

indicator = True;
for g in range(2,int(math.sqrt(num))+1):
    if num%g == 0:
        indicator = False
    #u can print g here
#outside of for loop, g is no longer in the local frame, it is now undefined
if indicator:
    b.append(num)

答案 1 :(得分:0)

尝试print(g)时遇到的问题是生成器表达式的作用域规则。 Python 2和Python 3在变量/名称的作用域和生存期方面有所不同:

Python 2

In [1]: list((a for a in range(5))); print a
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-eb5a741c3a99> in <module>()
----> 1 list((a for a in range(5))); print a

NameError: name 'a' is not defined

In [2]: list([b for b in range(5)]); print b
4

在Python 2中,列表推导将表达式内部使用的名称“泄漏”到封闭范围内,即,在评估表达式之后可以访问这些名称,并将打印最后一个值。与此相反,生成器表达式不会将其名称“泄漏”到封闭范围内。

Python 3

In [1]: list((a for a in range(5))); print(a)                                   
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-1-b1aaa69684c6> in <module>
----> 1 list((a for a in range(5))); print(a)

NameError: name 'a' is not defined

In [2]: list([b for b in range(5)]); print(b)                                   
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-2-75ef5b1fd39f> in <module>
----> 1 list([b for b in range(5)]); print(b)

NameError: name 'b' is not defined

在Python 3中,列表推导和生成器表达式都不会将表达式中使用的名称“泄漏”到封闭范围内,即,在对表达式求值后,这些名称是未定义的。

您的案子

因此,无论您使用哪个Python版本,您都将无法访问变量g。如果要查看g的所有值,则可以使用以下内容:

import math

def printret(x):
    print(x)
    return x

b=[]
for num in range(2,1000):
    if num>1:
        if all(num%printret(g)!=0 for g in range(2,int(math.sqrt(num))+1)):
            b.append(num)
print(b)

另一方面,您知道 g的最后一个值为int(math.sqrt(num)),因此您可以打印以下内容:

import math

b=[]
for num in range(2,1000):
    if num>1:
        if all(num%g!=0 for g in range(2,int(math.sqrt(num))+1)):
            print(int(math.sqrt(num)))
            b.append(num)
print(b)