Short-circuit evaluation like Python's "and" while storing results of checks
<p>I have multiple expensive functions that return results.  I want to return a tuple of the results of all the checks if all the checks succeed.  However, if one check fails I don't want to call the later checks, like the short-circuiting behavior of <code>and</code>.  I could nest <code>if</code> statements, but that will get out of hand if there are a lot of checks.  How can I get the short-circuit behavior of <code>and</code> while also storing the results for later use?</p>

<pre><code>def check_a():
    # do something and return the result,
    # for simplicity, just make it "A"
    return "A"

def check_b():
    # do something and return the result,
    # for simplicity, just make it "B"
    return "B"

...
</code></pre>

<p>This doesn't short-circuit:</p>

<pre><code>a = check_a()
b = check_b()
c = check_c()

if a and b and c:
    return a, b, c
</code></pre>

<p>This is messy if there are many checks:</p>

<pre><code>if a:
   b = check_b()

   if b:
      c = check_c()

      if c:
          return a, b, c
</code></pre>

<p>Is there a shorter way to do this?</p>

<p>main logic:</p>

<pre><code>results = list(takewhile(lambda x: x, map(lambda x: x(), function_list)))
if len(results) == len(function_list):
  return results
</code></pre>

<p>you can learn a lot about collection transformations if you look at all methods of an api like <a href="http://www.scala-lang.org/api/2.11.7/#scala.collection.immutable.List" rel="nofollow">http://www.scala-lang.org/api/2.11.7/#scala.collection.immutable.List</a> and search/implement python equivalents</p>

<p>logic with setup and alternatives:</p>

<pre><code>import sys
if sys.version_info.major == 2:
  from collections import imap
  map = imap

def test(bool):
  def inner():
    print(bool)
    return bool
  return inner

def function_for_return():
  function_list = [test(True),test(True),test(False),test(True)]

  from itertools import takewhile

  print("results:")

  results = list(takewhile(lambda x:x,map(lambda x:x(),function_list)))
  if len(results) == len(function_list):
    return results

  print(results)
  #personally i prefer another syntax:
  class Iterator(object):
    def __init__(self,iterable):
      self.iterator = iter(iterable)

    def __next__(self):
      return next(self.iterator)

    def __iter__(self):
      return self

    def map(self,f):
      return Iterator(map(f,self.iterator))

    def takewhile(self,f):
      return Iterator(takewhile(f,self.iterator))

  print("results2:")
  results2 = list(
    Iterator(function_list)
      .map(lambda x:x())
      .takewhile(lambda x:x)    
  )

  print(results2)

  print("with additional information")
  function_list2 = [(test(True),"a"),(test(True),"b"),(test(False),"c"),(test(True),"d")]
  results3 = list(
    Iterator(function_list2)
      .map(lambda x:(x[0](),x[1]))
      .takewhile(lambda x:x[0])    
  )
  print(results3)

function_for_return()
</code></pre>

python short-circuiting