当我使用mylist + [ newmember ]
语法时,我的算法运行得很好。
class Node:
def __init__( self, label, value, child1=None, child2=None ):
self.label = label
self.val = value
self.children = []
if child1 != None:
self.children.append( child1 )
if child2 != None:
self.children.append( child2 )
b = Node( 'b', 3 )
c = Node( 'c', 12 )
a = Node( 'a', 5, b, c )
def check( path, item, slns ):
node = path[ -1 ]
if node.val == item:
slns.append( path )
if len( node.children ) > 0:
for i in node.children:
check( path + [ i ], item, slns ) # <<<< This works!
def search( root, item ):
slns = []
check( [ root ], item, slns )
return slns
resultpath = search( a, 12 )
for i in resultpath:
for j in i:
print( j.label )
但是在使用带有mylist.append( newmember )
语法(即check( path.append( i ), item, slns
)的注释行(第21行)尝试之后,我将其更改为此。我收到了这个错误。
Traceback (most recent call last):
File "tree2.py", line 28, in <module>
resultpath = search( a, 12 )
File "tree2.py", line 25, in search
check( [ root ], item, slns )
File "tree2.py", line 21, in check
check( path.append( i ), item, slns )
# <<<< This works!
File "tree2.py", line 16, in check
node = path[ -1 ]
TypeError: 'NoneType' object is not subscriptable
我在这个网站上阅读其他答案让我相信,在追加项目而不是列表时,除了性能差异之外,附加到列表的两种方式是等效的。你能解释为什么path.append( i )
和path + [ i ]
会在这种情况下产生不同的结果,以及为什么会出现这种错误?
答案 0 :(得分:2)
区别在于lst.append(item)
将item
附加到现有列表(就地),并在None
运算符(+
)时返回__add__
返回连接的结果(新列表)。
因此,当您致电check( path.append(i), item, slns )
时,您确实会修改列表path
,但您实际上会调用check(None , item, slns )
而不是新列表作为第一个参数。
答案 1 :(得分:1)
list.append()
是一个就地操作,它不返回任何内容,因此该调用返回None
。
当你这样做时 -
check( path.append( i ), item, slns )
您实际上是将path.append()
的返回值发送给check()
,path.append()
的返回值为无,因此您发送None
作为第一个参数,导致您的问题。
我会说,如果第一种方法有效,那看起来更干净。当您使用path.append()
时,它最终会就地附加path
对象,并且由于您没有在任何地方创建新路径list
,因此它将始终更新相同的路径对象,你最终会得到错误的结果。
执行list + list1
时,创建一个新列表,表达式返回该值。
另外,一个建议是,不是创建slns
作为列表列表,而是应该使用slns.extend(path)
创建一个简单的列表,然后将其视为一个简单的列表,示例 -
def check( path, item, slns ):
node = path[ -1 ]
if node.val == item:
slns.extend( path )
if len( node.children ) > 0:
for i in node.children:
check( path + [ i ], item, slns ) # <<<< This works!
def search( root, item ):
slns = []
check( [ root ], item, slns )
return slns
resultpath = search( a, 12 )
for i in resultpath:
print( i.label )
python中的 list.extend
将它作为参数接收的iterable元素(不是iterable本身)附加到列表中(同样这也是一个就地操作并且不返回任何东西)。