title: Python - How do I write a more efficient, Pythonic reduce?
body: <p>I'm trying to build a very lightweight Node class to serve as a Python-based hierarchy search tool. See the definition below.</p>
  
  <pre><code>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
  </code></pre>
  
  <p><code>contains</code> seems to be a textbook case of functional programming (pulled directly from <a href="http://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf" rel="nofollow" title="Why Functional Programming Matters">Why Functional Programming Matters</a>).</p>
  
  <p>Question: is there a more efficient or Pythonic way of writing <code>contains</code>? I know that <code>map</code> is usually replaced by list comprehension, but I hadn't seen a better way of doing <code>reduce</code>-based recursion.</p>
  
  <p>Thanks,</p>
  
  <p>Mike</p>
  
  <p>===EDITED ... HERE'S THE REDONE CLASS TAKING INTO ACCOUNT THE ANSWER AND COMMENTS===</p>
  
  <pre><code>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
  </code></pre>