1

たとえば、二分探索木が与えられた場合:

        9
            8
    7
5
    3
        2

a と b の間 (両端を含む) の値を持つノードの順序付きリストを取得したいと思います。

再帰ヘルパー関数を実装しました:

def _range(root, a, b):
node_list = []
if root.left:
    node_list.append(_range(root.left, a, b))
if root.value >= a and root.value <= b:
    node_list.append(root)
if root.right:
    node_list.append(_range(root.right, a, b))
return node_list

それは私に与えます:

[[[BTNode: 2], BTNode: 3], BTNode: 5, [BTNode: 7, [[BTNode: 8], BTNode: 9]]]

ただし、次のものが必要です。

[BTNode: 2, BTNode: 3, BTNode: 5, BTNode: 7, BTNode: 8, BTNode: 9]

とにかくリストを平坦化する方法はありますか? 私がやっていることはリストを別のリストに追加していることに気づきましたが、コードを壊さずにこれを修正する方法がわかりません。

4

1 に答える 1

0

append引数として渡すオブジェクトをリストに追加するため、明らかにネストされたリストになります。結果を連結したいので、使用したいlist.extend(または+=演算子):

>>> from collections import namedtuple
>>> class Node(namedtuple('Node', 'value left right')):
...     # I reimplement __str__ just to avoid too much output later
...     def __repr__(self):
...             return 'Node(%r)' % self.value
...     __str__ = __repr__
... 
>>> def make_node(value, left=None, right=None):
...     return Node(value, left, right)
... 
>>> def _range(root, a, b):
...     node_list = []
...     if root.left:
...             node_list.extend(_range(root.left, a, b))
...     if a <= root.value <= b:
...             node_list.append(root)
...     if root.right:
...             node_list.extend(_range(root.right, a, b))
...     return node_list
... 
>>> tree = make_node(5, make_node(3, make_node(2)), make_node(7, None, make_node(8, None, make_node(9))))
>>> _range(tree, 1, 3)
[Node(2), Node(3)]
>>> _range(tree, 1, 10)
[Node(2), Node(3), Node(5), Node(7), Node(8), Node(9)]

それを行う別の方法は、リストをパラメーターとして渡すことです。

>>> def _range(root, a, b, node_list=None):
...     if node_list is None:
...             # Note: do *not* use "[]" as a default!
...             node_list = []
...     if root.left:
...             _range(root.left, a, b, node_list)
...     if a <= root.value <= b:
...             node_list.append(root)
...     if root.right:
...             _range(root.right, a, b, node_list)
...     return node_list
... 
>>> _range(tree, 1, 3)
[Node(2), Node(3)]
>>> _range(tree, 1, 10)
[Node(2), Node(3), Node(5), Node(7), Node(8), Node(9)]
于 2012-11-06T18:16:38.300 に答える