Mik*_*and 10 python algorithm tree graph
我正在尝试构建一个非常轻量级的Node类,作为基于Python的层次结构搜索工具.请参阅以下定义.
from functools import reduce
from operator import or_
class Node:
def __init__(self, name):
self.name = name
self.children = []
def add_child(self, child_node):
self.children.append(child_node)
def contains(self, other_node):
if self == other_node:
return True
elif other_node in self.children:
return True
else:
return reduce(or_, [child.contains(other_node)
for child in self.children], False)
def is_contained_by(self, other_node):
return other_node.contains(self)
def __eq__(self, other_node):
return self.name == other_node.name
def __de__(self, other_node):
return self.name != other_node.name
Run Code Online (Sandbox Code Playgroud)
contains
似乎是函数式编程的教科书案例(直接从" 为什么功能编程事项"中提取).
问题:是否有更高效或Pythonic的写作方式contains
?我知道这map
通常被列表理解所取代,但我还没有看到更好的reduce
基于做递归的方法.
谢谢,
麦克风
===已经编辑...这里的REDONE课程考虑了答案和评论===
class Node:
def __init__(self, name):
self.name = name
self.children = []
def add_child(self, child_node):
# Hattip to lazyr for catching this.
if self.contains(child_node) or child_node.contains(self):
raise TreeError('A relationship is already defined.')
else:
self.children.append(child_node)
def contains(self, other_node):
# Hattip to lazyr for pointing out any() and to Jochen Ritzel for
# eliminating the silly child check.
return (self == other_node or
any(child.contains(other_node) for child in self.children))
def is_contained_by(self, other_node):
return other_node.contains(self)
def __eq__(self, other_node):
return self.name == other_node.name
def __de__(self, other_node):
return self.name != other_node.name
def __repr__(self):
return self.name
Run Code Online (Sandbox Code Playgroud)
我认为(未经测试)你reduce
应该使用any
这样的,这将在第一次击中时停止:
return any(child.contains(other_node) for child in self.children)
Run Code Online (Sandbox Code Playgroud)
顺便说一句,你的意思是用于a.contains(b)
返回False
时a == b
和len(a.children) > 0
?
编辑:如果您的树包含一个循环,如下所示:
a = Node("a")
b = Node("b")
a.add_child(a)
a.add_child(b)
Run Code Online (Sandbox Code Playgroud)
然后
a.contains(b)
Run Code Online (Sandbox Code Playgroud)
会破坏程序.您可能需要在内部contains
或内部检查add_child
,具体取决于您最常使用的内容.