Python:类声明中的递归



我正试图在Python中的类声明中实现一个递归函数。但是,该函数似乎不接受参数。如果我在类之外声明一个递归函数,它就可以工作。

[Awhile循环][1]也可以。(参见"遍历值"(。IMHO,我的头撞在键盘上,已经足够允许发布SO帖子了。

class Node:
def __init__(self, value):
self.data = value
self.next = None
def traverse(self, node):
print(node.data)
if (node.next == None):
return
else:
node.traverse(node.next)

>>> a = Node('a')
>>> b = Node('b')
>>> c = Node('c')
>>> a.next = b
>>> b.next = c
>>> Node.traverse(a)
Traceback (most recent call last):
File "<pyshell#62>", line 1, in <module>
Node.traverse(a)
TypeError: traverse() missing 1 required positional argument: 'node'

[1]: https://medium.com/@kojinoshiba/data-structures-in-python-series-1-linked-lists-d9f848537b4d

更典型的实现是.

节点代码

class Node:
def __init__(self, value):
self.data = value
self.next = None

def traverse(self):               # instance method (no 2nd argument node)
if self:                      # check if node
print(self.data)          # output data
if self.next:             # check for next node
self.next.traverse()  # recursive call to next node if any

测试

a = Node('a')
b = Node('b')
c = Node('c')
a.next = b
b.next = c
a.traverse()     # Note: Node.traverse(a) also works
# This is because
# When you call an instance method (e.g. traverse) from an
# instance object (e.g. a), Python automatically passes 
# that instance object as the first argument (in addition
# to any other arguments) to the function call
# Thus: a.traverse() becomes Node.traverse(a)

输出

a
b
c

您需要使traverse成为一个类方法。目前,它说您缺少node参数,因为在Node.traverse(a)行中您提供了self=a,而不是node=a

class Node:
def __init__(self, value):
self.data = value
self.next = None
@classmethod # This is the only addition needed :) 
def traverse(self, node):
print(node.data)
if node.next is None:
return
else:
node.traverse(node.next)

Python Cookbook,第117页,您会发现这个配方是解决这个问题的更好方案:

class Node:
def __init__(self, value):
self._value = value
self._children = []
def __repr__(self):
return 'Node({!r})'.format(self._value)
def add_child(self, node):
self._children.append(node)
def __iter__(self):
return iter(self._children)
def depth_first(self):
yield self
for c in self:
yield from c.depth_first()

if __name__ == '__main__':
root = Node(0)
child1 = Node(1)
child2 = Node(2)
root.add_child(child1)
root.add_child(child2)
child1.add_child(Node(3))
child1.add_child(Node(4))
child2.add_child(Node(5))
for ch in root.depth_first():
print(ch)

试着使用这个。

最新更新