Python:简化许多if语句

时间:2013-03-20 23:44:33

标签: python if-statement binary-tree traversal

我有一个遍历树的函数,并将元素作为列表返回。有没有办法简化treeToList::traverse中的所有if语句,因为它看起来有点多余?

#!/usr/bin/python

def enum(**enums):
  return type('Enum', (), enums)

Order = enum(PREORDER=0, INORDER=1, POSTORDER=2)
def treeToList(root, order=Order.INORDER):
  ret = list()
  def traverse(node, order):
    if order == Order.PREORDER: ret.append(node.data)
    if node.right != None: traverse(node.right, order)
    if order == Order.INORDER: ret.append(node.data)
    if node.down != None: traverse(node.down, order)
    if order == Order.POSTORDER: ret.append(node.data)
  traverse(root, order)
  return ret

class node:
  def __init__(self, data=None):
    self.data = data
    self.down = None
    self.right = None

if __name__ == '__main__':
  root = node('F')
  root.right = node('B')
  root.down = node('G')
  root.right.right = node('A')
  root.right.down = node('D')
  root.down.down = node('I')
  root.right.down.right = node('C')
  root.right.down.down = node('E')
  root.down.down.right = node('H')

  print treeToList(root, Order.PREORDER)
  print treeToList(root, Order.INORDER)
  print treeToList(root, Order.POSTORDER)

输出

['F', 'B', 'A', 'D', 'C', 'E', 'G', 'I', 'H']
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
['A', 'C', 'E', 'D', 'B', 'H', 'I', 'G', 'F']

4 个答案:

答案 0 :(得分:5)

好吧,如果你摆脱了封闭......纯粹的功能可能更清晰:

def treeToList(node, order=Order.INORDER):
    if node is None:
        return []

    right = treeToList(node.right, order)
    down = treeToList(node.down, order)
    current = [node.data]

    if order == Order.PREORDER:
        return current + right + down

    if order == Order.INORDER:
        return right + current + down

    if order == Order.POSTORDER:
        return right + down + current

但当然会建立很多中间列表。

答案 1 :(得分:2)

我唯一想到的是:

def treeToList(root, order=Order.INORDER):
    ret = list()
    def inorder_traversal(node):
        if node is not None:
            inorder_traversal(node.right)
            ret.append(node.data)
            inorder_traversal(node.down)

    def preorder_traversal(node):
        if node is not None:
            ret.append(node.data)
            preorder_traversal(node.right)
            preorder_traversal(node.down)

    def postorder_traversal(node):
        if node is not None:
            postorder_traversal(node.right)
            postorder_traversal(node.down)
            ret.append(node.data)

    if order == Order.PREORDER:
        preorder_traversal(node)
    elif order == Order.INORDER:
        inorder_traversal(node)
    else:
        postorder_traversal(node)

    return ret

答案 2 :(得分:2)

我不认为在不重新组织算法的情况下消除三个if order语句是一种好方法。 ret.append发生的位置取决于值,因此您几乎必须以这种或那种方式对其进行三次检查。

但是有一种显而易见的方法可以重组事物以删除一对if

def traverse(node, order):
    if node is None: return
    if order == Order.PREORDER: ret.append(node.data)
    traverse(node.right, order)
    if order == Order.INORDER: ret.append(node.data)
    traverse(node.down, order)
    if order == Order.POSTORDER: ret.append(node.data)

当然它只有一行,但它只有4 if而不是6。

另一种可能性是改变事物以跟踪所有三个位置,并在事后插入适当的位置:

def traverse(node, order):
    if node is None: return
    prepos = len(ret)
    traverse(node.right, order)
    inpos = len(ret)
    traverse(node.down, order)
    postpos = len(ret)
    pos = (prepos, inpos, postpos)[order]
    ret[pos:pos+1] = node.data

这会删除所有if,但我不认为结果更容易阅读或理解......

真的,让这个更易于阅读和理解的方法可能是转换为功能算法(递归可变算法很难通过考虑)......但这只会使三个if体更大,不要摆脱他们。

答案 3 :(得分:0)

尝试类似

的内容
if order in (Order.PREORDER, Order.INORDER, ...):
    ret.append(node.data)

<击> 挑剔

你应该有多条线的条件

if cond:
    pass

而不是

if cond: pass

在与is而不是is notNone进行比较时,还要考虑使用==!=