理解赋值错误前的引用

Understanding reference before assignment error

下面的代码,

def is_leaf(tree):
    return type(tree) != list

def count_leaf(tree):
    if is_leaf(tree):
        return 1
    branch_counts = [count_leaf(b) for b in tree]
    return sum(branch_counts)

在表达式 sum(branch_counts).

中引用 branch_counts 时不会抛出此类错误

但是下面的代码,

def is_leaf(tree):
    return type(tree) != list

def count_leaf(tree):
    if is_leaf(tree):
        return 1
    for b in tree:
        branch_counts = [count_leaf(b)]
    return sum(branch_counts)

在表达式 sum(branch_counts).

中引用 branch_counts 时会抛出此类错误

第一种情况branch_counts还没有通过计算列表理解表达式来评估,为什么第一种情况没有抛出错误?

如果树为空,[],则 branch_counts 变量未初始化。

为了使代码等同于第一个,修改如下:

def count_leaf(tree):
    if is_leaf(tree):
        return 1
    branch_counts = list()
    for b in tree:
        branch_counts.append(count_leaf(b))
    return sum(branch_counts)

请注意..第一个和第二个代码不同,如果您希望它完成相同的工作,则在第二个代码中将行更改为

branch_counts.append(count_leaf(b))

在这种情况下不会打印任何内容,因为 s

中没有任何内容
a=[]
for s in a:
   print "hi"

"",{},()

也是如此

如果 tree 为空,那么第二种情况不会创建变量

即)

a=[]

for s in a:
    c=s


print (c)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-96-2cd6ee2c70b0> in <module>()
----> 1 c

NameError: name 'c' is not defined 

第一种情况:

c=[s for s in a]
c
[]

您的程序中的一个错误是:

branch_counts = [count_leaf(b)]

一直只创建元素一的列表

它必须在循环之前的某个地方启动,例如 branch_counts = []

然后在循环中:

branch_counts.append(count_leaf(b))

在你的第一个例子中,因为你使用了列表推导,branch_counts 被初始化为一个空列表:

>>> branch_counts = [count_leaf(b) for b in []]]
[]

在第二个例子中,for循环没有运行,因为tree中没有b。所以 branch_counts 永远不会被分配任何东西。

>>> for b in []:
>>>     branch_counts = [count_leaf(b)]
>>> sum(branch_counts)
NameError: name 'branch_counts' is not defined

除此之外,正如其他人指出的那样,在第二个示例中,每次循环 运行s 时都会重新分配 branch_count(而不是使用 append() 添加内容)。