python minmax using only recursion











up vote
1
down vote

favorite
1












I am trying to build a function that takes in a list and returns a tuple of (min, max).



For example,



[2,1,4,9,4.5]


would return



(1, 9)


I am trying to use only recursion and want to perform this task without using other things that would make this very easy (such as min(),max(),sort(),sorted(),loop..etc)



So far, I have been able to create function that find maximum



def findmax(alist):
if len(alist) <= 1:
return tuple(alist)
elif len(alist) == 2:
if alist[0] >= alist[1]:
return findmax([alist[0]])
elif alist[0] <= alist[1]:
return findmax([alist[1]])
elif len(alist) > 2:
if alist[0] >= alist[1]:
return findmax([alist[0]] + alist[2:])
elif alist[0] <= alist[1]:
return findmax(alist[1:])


which



findmax([2,1,4,9,4.5])


returns



(9,)


and a function that find minimum (which is not too different)



def findmin(alist):
if len(alist) <= 1:
return tuple(alist)
elif len(alist) == 2:
if alist[0] >= alist[1]:
return findmin([alist[1]])
elif alist[0] <= alist[1]:
return findmin([alist[0]])
elif len(alist) > 2:
if alist[0] >= alist[1]:
return findmin(alist[1:])
elif alist[0] <= alist[1]:
return findmin([alist[0]] + alist[2:])


which



findmin([2,1,4,9,4.5])


returns



(1,)


Is there a way to put this two separate functions into one using only recursion so that it would return a desired result of



(1, 9)


Any help would really be appreciated.










share|improve this question


























    up vote
    1
    down vote

    favorite
    1












    I am trying to build a function that takes in a list and returns a tuple of (min, max).



    For example,



    [2,1,4,9,4.5]


    would return



    (1, 9)


    I am trying to use only recursion and want to perform this task without using other things that would make this very easy (such as min(),max(),sort(),sorted(),loop..etc)



    So far, I have been able to create function that find maximum



    def findmax(alist):
    if len(alist) <= 1:
    return tuple(alist)
    elif len(alist) == 2:
    if alist[0] >= alist[1]:
    return findmax([alist[0]])
    elif alist[0] <= alist[1]:
    return findmax([alist[1]])
    elif len(alist) > 2:
    if alist[0] >= alist[1]:
    return findmax([alist[0]] + alist[2:])
    elif alist[0] <= alist[1]:
    return findmax(alist[1:])


    which



    findmax([2,1,4,9,4.5])


    returns



    (9,)


    and a function that find minimum (which is not too different)



    def findmin(alist):
    if len(alist) <= 1:
    return tuple(alist)
    elif len(alist) == 2:
    if alist[0] >= alist[1]:
    return findmin([alist[1]])
    elif alist[0] <= alist[1]:
    return findmin([alist[0]])
    elif len(alist) > 2:
    if alist[0] >= alist[1]:
    return findmin(alist[1:])
    elif alist[0] <= alist[1]:
    return findmin([alist[0]] + alist[2:])


    which



    findmin([2,1,4,9,4.5])


    returns



    (1,)


    Is there a way to put this two separate functions into one using only recursion so that it would return a desired result of



    (1, 9)


    Any help would really be appreciated.










    share|improve this question
























      up vote
      1
      down vote

      favorite
      1









      up vote
      1
      down vote

      favorite
      1






      1





      I am trying to build a function that takes in a list and returns a tuple of (min, max).



      For example,



      [2,1,4,9,4.5]


      would return



      (1, 9)


      I am trying to use only recursion and want to perform this task without using other things that would make this very easy (such as min(),max(),sort(),sorted(),loop..etc)



      So far, I have been able to create function that find maximum



      def findmax(alist):
      if len(alist) <= 1:
      return tuple(alist)
      elif len(alist) == 2:
      if alist[0] >= alist[1]:
      return findmax([alist[0]])
      elif alist[0] <= alist[1]:
      return findmax([alist[1]])
      elif len(alist) > 2:
      if alist[0] >= alist[1]:
      return findmax([alist[0]] + alist[2:])
      elif alist[0] <= alist[1]:
      return findmax(alist[1:])


      which



      findmax([2,1,4,9,4.5])


      returns



      (9,)


      and a function that find minimum (which is not too different)



      def findmin(alist):
      if len(alist) <= 1:
      return tuple(alist)
      elif len(alist) == 2:
      if alist[0] >= alist[1]:
      return findmin([alist[1]])
      elif alist[0] <= alist[1]:
      return findmin([alist[0]])
      elif len(alist) > 2:
      if alist[0] >= alist[1]:
      return findmin(alist[1:])
      elif alist[0] <= alist[1]:
      return findmin([alist[0]] + alist[2:])


      which



      findmin([2,1,4,9,4.5])


      returns



      (1,)


      Is there a way to put this two separate functions into one using only recursion so that it would return a desired result of



      (1, 9)


      Any help would really be appreciated.










      share|improve this question













      I am trying to build a function that takes in a list and returns a tuple of (min, max).



      For example,



      [2,1,4,9,4.5]


      would return



      (1, 9)


      I am trying to use only recursion and want to perform this task without using other things that would make this very easy (such as min(),max(),sort(),sorted(),loop..etc)



      So far, I have been able to create function that find maximum



      def findmax(alist):
      if len(alist) <= 1:
      return tuple(alist)
      elif len(alist) == 2:
      if alist[0] >= alist[1]:
      return findmax([alist[0]])
      elif alist[0] <= alist[1]:
      return findmax([alist[1]])
      elif len(alist) > 2:
      if alist[0] >= alist[1]:
      return findmax([alist[0]] + alist[2:])
      elif alist[0] <= alist[1]:
      return findmax(alist[1:])


      which



      findmax([2,1,4,9,4.5])


      returns



      (9,)


      and a function that find minimum (which is not too different)



      def findmin(alist):
      if len(alist) <= 1:
      return tuple(alist)
      elif len(alist) == 2:
      if alist[0] >= alist[1]:
      return findmin([alist[1]])
      elif alist[0] <= alist[1]:
      return findmin([alist[0]])
      elif len(alist) > 2:
      if alist[0] >= alist[1]:
      return findmin(alist[1:])
      elif alist[0] <= alist[1]:
      return findmin([alist[0]] + alist[2:])


      which



      findmin([2,1,4,9,4.5])


      returns



      (1,)


      Is there a way to put this two separate functions into one using only recursion so that it would return a desired result of



      (1, 9)


      Any help would really be appreciated.







      python recursion minmax






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 7 at 0:57









      1231231231231

      391




      391
























          5 Answers
          5






          active

          oldest

          votes

















          up vote
          1
          down vote













          I find that these sorts of problems tend to be simpler than you expect. Let the recursion do the work:



          def find_min_max(a_list):

          if a_list:
          head, *tail = a_list

          if tail:
          minimum, maximum = find_min_max(tail)

          return [head, minimum][minimum < head], [head, maximum][maximum > head]

          return head, head

          return a_list


          USAGE



          >>> find_min_max([2, 1, 4, 9, 4.5])
          (1, 9)
          >>> find_min_max('elephant')
          ('a', 't')
          >>>


          This solution is Python 3 specific but can be easily modified for Python 2 & 3 compatibility.






          share|improve this answer






























            up vote
            1
            down vote













            Below, minmax is expressed using continuation-passing style. In this style, it's as if our state variables are pulled out of the aether. For additional examples of other programs written using this style, please see this answer.



            from math import inf

            def first (xs):
            return xs[0]

            def rest (xs):
            return xs[1:]

            def tuple2 (a, b):
            return (a, b)

            def minmax (xs = , then = tuple2):
            if not xs: # base case: no `x`
            return then (inf, -inf)
            else: # inductive case: at least one `x`
            return minmax
            ( rest(xs)
            , lambda a, b:
            then
            ( min (a, first (xs))
            , max (b, first (xs))
            )
            )

            print (minmax ([ 2, 1, 4, 9, 4.5 ]))
            # (1, 9)

            print (minmax ())
            # (inf, -inf)


            min and max are defined as



            def min (a, b)
            if a < b:
            return a
            else:
            return b

            def max (a, b)
            if a > b:
            return a
            else:
            return b





            share|improve this answer























            • You implemented minmax() by calling min() and max() which the OP said couldn't be used! If we can simply call min() and max(), we don't need any of this extra logic: minmax = lambda x: (min(x), max(x))
              – cdlane
              Nov 7 at 18:35












            • @cdlane that would iterate through x twice. This algorithm does not do that. Simple min and max definitions added.
              – user633183
              Nov 7 at 18:59


















            up vote
            1
            down vote













            To find either max or min separately is easy. What is difficult is to find both max and min through recursive calls. Tail recursion is exactly for this (maintain and update status of variables through recursive calls) and is usually straightforward to write:



            def findminmax(L):
            def inner(L1, min, max):
            if L1 == :
            return (min, max)
            elif L1[0] > max:
            return inner(L1[1:], min, L1[0])
            elif L1[0] < min:
            return inner(L1[1:], L1[0], max)
            else:
            return inner(L1[1:], min, max)
            return inner(L[1:], L[0], L[0])

            findminmax([2,1,4,9,4.5])
            # => (1, 9)


            No need for assignment and fancy list indexing. Only the most basic list operation is needed. The recursion structure is clear and very standard (obviously see base case, reduction and function recursive call) and the code is also very readable as plain English.



            Update



            A little modification to handle the string input and empty list or string input:



            def findminmax(LS):
            def inner(LS1, min, max):
            if not LS1:
            return (min, max)
            elif LS1[0] > max:
            return inner(LS1[1:], min, LS1[0])
            elif LS1[0] < min:
            return inner(LS1[1:], LS1[0], max)
            else:
            return inner(LS1[1:], min, max)
            try:
            return inner(LS[1:], LS[0], LS[0])
            except IndexError:
            print("Oops! That was no valid input. Try again...")

            findminmax([2,1,4,9,4.5])
            # => (1, 9)

            findminmax([2])
            # => (2, 2)

            findminmax('txwwadga')
            # => ('a', 'x')

            findminmax('t')
            # => ('t', 't')

            findminmax() # empty list
            # => Oops! That was no valid input. Try again...

            findminmax('') # empty string
            # => Oops! That was no valid input. Try again...





            share|improve this answer























            • I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
              – user633183
              Nov 7 at 15:22










            • You're inner() nested function checks if L1 is empty but your outer findminmax() fails to check if L is empty so dies with IndexError: list index out of range
              – cdlane
              Nov 7 at 18:27










            • @cdlane thanks for your valuable comment. I learnt something important from you. The answer is updated now. If you have better ideas, feel free to edit it
              – englealuze
              Nov 8 at 9:01


















            up vote
            0
            down vote













            You can add another def (read comments):



            def f(l):
            return findmin(l)+findmax(l) # Also you can do: `(findmin(l)[0],findmax(l)[0])`


            Now to call it, do:



            print(f([2,1,4,9,4.5]))


            Output would be:



            (1, 9)





            share|improve this answer




























              up vote
              0
              down vote













              You're definitely over-complicating the recursive function. Both minimum and maximum can be returned in a tuple with the following recursive code.



              my_list = [2,1,4,9,4.5]

              def recursive_min_max(list_a, pos, biggest, smallest):
              if pos != len(list_a) - 1:
              biggest_new = list_a[pos] if biggest == None else list_a[pos] if list_a[pos] > biggest else biggest
              smallest_new = list_a[pos] if smallest == None else list_a[pos] if list_a[pos] < smallest else smallest
              return recursive_min_max(list_a, pos + 1, biggest_new, smallest_new)
              return (biggest,smallest)


              print(recursive_min_max(my_list, 0, None, None))


              At each step, the current list item is being compared to the current biggest and smallest elements. If they are bigger/smaller, the current value replaces them.






              share|improve this answer

















              • 2




                If you apply this solution to the list [1], you should get (1, 1) but instead you get (None, None). If you apply this solution to the empty list, it fails with IndexError: list index out of range,
                – cdlane
                Nov 7 at 8:09










              • There seems to be something wrong in the logic. If I set my_list = [112, 97], I get back (112, 112) as a result. Changing if pos != len(list_a) - 1 to simply if pos < len(list_a) seems to help. Also return (biggest,smallest) is backward.
                – cdlane
                Nov 7 at 8:47











              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














               

              draft saved


              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53182287%2fpython-minmax-using-only-recursion%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              5 Answers
              5






              active

              oldest

              votes








              5 Answers
              5






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              1
              down vote













              I find that these sorts of problems tend to be simpler than you expect. Let the recursion do the work:



              def find_min_max(a_list):

              if a_list:
              head, *tail = a_list

              if tail:
              minimum, maximum = find_min_max(tail)

              return [head, minimum][minimum < head], [head, maximum][maximum > head]

              return head, head

              return a_list


              USAGE



              >>> find_min_max([2, 1, 4, 9, 4.5])
              (1, 9)
              >>> find_min_max('elephant')
              ('a', 't')
              >>>


              This solution is Python 3 specific but can be easily modified for Python 2 & 3 compatibility.






              share|improve this answer



























                up vote
                1
                down vote













                I find that these sorts of problems tend to be simpler than you expect. Let the recursion do the work:



                def find_min_max(a_list):

                if a_list:
                head, *tail = a_list

                if tail:
                minimum, maximum = find_min_max(tail)

                return [head, minimum][minimum < head], [head, maximum][maximum > head]

                return head, head

                return a_list


                USAGE



                >>> find_min_max([2, 1, 4, 9, 4.5])
                (1, 9)
                >>> find_min_max('elephant')
                ('a', 't')
                >>>


                This solution is Python 3 specific but can be easily modified for Python 2 & 3 compatibility.






                share|improve this answer

























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  I find that these sorts of problems tend to be simpler than you expect. Let the recursion do the work:



                  def find_min_max(a_list):

                  if a_list:
                  head, *tail = a_list

                  if tail:
                  minimum, maximum = find_min_max(tail)

                  return [head, minimum][minimum < head], [head, maximum][maximum > head]

                  return head, head

                  return a_list


                  USAGE



                  >>> find_min_max([2, 1, 4, 9, 4.5])
                  (1, 9)
                  >>> find_min_max('elephant')
                  ('a', 't')
                  >>>


                  This solution is Python 3 specific but can be easily modified for Python 2 & 3 compatibility.






                  share|improve this answer














                  I find that these sorts of problems tend to be simpler than you expect. Let the recursion do the work:



                  def find_min_max(a_list):

                  if a_list:
                  head, *tail = a_list

                  if tail:
                  minimum, maximum = find_min_max(tail)

                  return [head, minimum][minimum < head], [head, maximum][maximum > head]

                  return head, head

                  return a_list


                  USAGE



                  >>> find_min_max([2, 1, 4, 9, 4.5])
                  (1, 9)
                  >>> find_min_max('elephant')
                  ('a', 't')
                  >>>


                  This solution is Python 3 specific but can be easily modified for Python 2 & 3 compatibility.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 7 at 18:30

























                  answered Nov 7 at 8:07









                  cdlane

                  16.5k21042




                  16.5k21042
























                      up vote
                      1
                      down vote













                      Below, minmax is expressed using continuation-passing style. In this style, it's as if our state variables are pulled out of the aether. For additional examples of other programs written using this style, please see this answer.



                      from math import inf

                      def first (xs):
                      return xs[0]

                      def rest (xs):
                      return xs[1:]

                      def tuple2 (a, b):
                      return (a, b)

                      def minmax (xs = , then = tuple2):
                      if not xs: # base case: no `x`
                      return then (inf, -inf)
                      else: # inductive case: at least one `x`
                      return minmax
                      ( rest(xs)
                      , lambda a, b:
                      then
                      ( min (a, first (xs))
                      , max (b, first (xs))
                      )
                      )

                      print (minmax ([ 2, 1, 4, 9, 4.5 ]))
                      # (1, 9)

                      print (minmax ())
                      # (inf, -inf)


                      min and max are defined as



                      def min (a, b)
                      if a < b:
                      return a
                      else:
                      return b

                      def max (a, b)
                      if a > b:
                      return a
                      else:
                      return b





                      share|improve this answer























                      • You implemented minmax() by calling min() and max() which the OP said couldn't be used! If we can simply call min() and max(), we don't need any of this extra logic: minmax = lambda x: (min(x), max(x))
                        – cdlane
                        Nov 7 at 18:35












                      • @cdlane that would iterate through x twice. This algorithm does not do that. Simple min and max definitions added.
                        – user633183
                        Nov 7 at 18:59















                      up vote
                      1
                      down vote













                      Below, minmax is expressed using continuation-passing style. In this style, it's as if our state variables are pulled out of the aether. For additional examples of other programs written using this style, please see this answer.



                      from math import inf

                      def first (xs):
                      return xs[0]

                      def rest (xs):
                      return xs[1:]

                      def tuple2 (a, b):
                      return (a, b)

                      def minmax (xs = , then = tuple2):
                      if not xs: # base case: no `x`
                      return then (inf, -inf)
                      else: # inductive case: at least one `x`
                      return minmax
                      ( rest(xs)
                      , lambda a, b:
                      then
                      ( min (a, first (xs))
                      , max (b, first (xs))
                      )
                      )

                      print (minmax ([ 2, 1, 4, 9, 4.5 ]))
                      # (1, 9)

                      print (minmax ())
                      # (inf, -inf)


                      min and max are defined as



                      def min (a, b)
                      if a < b:
                      return a
                      else:
                      return b

                      def max (a, b)
                      if a > b:
                      return a
                      else:
                      return b





                      share|improve this answer























                      • You implemented minmax() by calling min() and max() which the OP said couldn't be used! If we can simply call min() and max(), we don't need any of this extra logic: minmax = lambda x: (min(x), max(x))
                        – cdlane
                        Nov 7 at 18:35












                      • @cdlane that would iterate through x twice. This algorithm does not do that. Simple min and max definitions added.
                        – user633183
                        Nov 7 at 18:59













                      up vote
                      1
                      down vote










                      up vote
                      1
                      down vote









                      Below, minmax is expressed using continuation-passing style. In this style, it's as if our state variables are pulled out of the aether. For additional examples of other programs written using this style, please see this answer.



                      from math import inf

                      def first (xs):
                      return xs[0]

                      def rest (xs):
                      return xs[1:]

                      def tuple2 (a, b):
                      return (a, b)

                      def minmax (xs = , then = tuple2):
                      if not xs: # base case: no `x`
                      return then (inf, -inf)
                      else: # inductive case: at least one `x`
                      return minmax
                      ( rest(xs)
                      , lambda a, b:
                      then
                      ( min (a, first (xs))
                      , max (b, first (xs))
                      )
                      )

                      print (minmax ([ 2, 1, 4, 9, 4.5 ]))
                      # (1, 9)

                      print (minmax ())
                      # (inf, -inf)


                      min and max are defined as



                      def min (a, b)
                      if a < b:
                      return a
                      else:
                      return b

                      def max (a, b)
                      if a > b:
                      return a
                      else:
                      return b





                      share|improve this answer














                      Below, minmax is expressed using continuation-passing style. In this style, it's as if our state variables are pulled out of the aether. For additional examples of other programs written using this style, please see this answer.



                      from math import inf

                      def first (xs):
                      return xs[0]

                      def rest (xs):
                      return xs[1:]

                      def tuple2 (a, b):
                      return (a, b)

                      def minmax (xs = , then = tuple2):
                      if not xs: # base case: no `x`
                      return then (inf, -inf)
                      else: # inductive case: at least one `x`
                      return minmax
                      ( rest(xs)
                      , lambda a, b:
                      then
                      ( min (a, first (xs))
                      , max (b, first (xs))
                      )
                      )

                      print (minmax ([ 2, 1, 4, 9, 4.5 ]))
                      # (1, 9)

                      print (minmax ())
                      # (inf, -inf)


                      min and max are defined as



                      def min (a, b)
                      if a < b:
                      return a
                      else:
                      return b

                      def max (a, b)
                      if a > b:
                      return a
                      else:
                      return b






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 7 at 18:58

























                      answered Nov 7 at 15:18









                      user633183

                      66.7k21130172




                      66.7k21130172












                      • You implemented minmax() by calling min() and max() which the OP said couldn't be used! If we can simply call min() and max(), we don't need any of this extra logic: minmax = lambda x: (min(x), max(x))
                        – cdlane
                        Nov 7 at 18:35












                      • @cdlane that would iterate through x twice. This algorithm does not do that. Simple min and max definitions added.
                        – user633183
                        Nov 7 at 18:59


















                      • You implemented minmax() by calling min() and max() which the OP said couldn't be used! If we can simply call min() and max(), we don't need any of this extra logic: minmax = lambda x: (min(x), max(x))
                        – cdlane
                        Nov 7 at 18:35












                      • @cdlane that would iterate through x twice. This algorithm does not do that. Simple min and max definitions added.
                        – user633183
                        Nov 7 at 18:59
















                      You implemented minmax() by calling min() and max() which the OP said couldn't be used! If we can simply call min() and max(), we don't need any of this extra logic: minmax = lambda x: (min(x), max(x))
                      – cdlane
                      Nov 7 at 18:35






                      You implemented minmax() by calling min() and max() which the OP said couldn't be used! If we can simply call min() and max(), we don't need any of this extra logic: minmax = lambda x: (min(x), max(x))
                      – cdlane
                      Nov 7 at 18:35














                      @cdlane that would iterate through x twice. This algorithm does not do that. Simple min and max definitions added.
                      – user633183
                      Nov 7 at 18:59




                      @cdlane that would iterate through x twice. This algorithm does not do that. Simple min and max definitions added.
                      – user633183
                      Nov 7 at 18:59










                      up vote
                      1
                      down vote













                      To find either max or min separately is easy. What is difficult is to find both max and min through recursive calls. Tail recursion is exactly for this (maintain and update status of variables through recursive calls) and is usually straightforward to write:



                      def findminmax(L):
                      def inner(L1, min, max):
                      if L1 == :
                      return (min, max)
                      elif L1[0] > max:
                      return inner(L1[1:], min, L1[0])
                      elif L1[0] < min:
                      return inner(L1[1:], L1[0], max)
                      else:
                      return inner(L1[1:], min, max)
                      return inner(L[1:], L[0], L[0])

                      findminmax([2,1,4,9,4.5])
                      # => (1, 9)


                      No need for assignment and fancy list indexing. Only the most basic list operation is needed. The recursion structure is clear and very standard (obviously see base case, reduction and function recursive call) and the code is also very readable as plain English.



                      Update



                      A little modification to handle the string input and empty list or string input:



                      def findminmax(LS):
                      def inner(LS1, min, max):
                      if not LS1:
                      return (min, max)
                      elif LS1[0] > max:
                      return inner(LS1[1:], min, LS1[0])
                      elif LS1[0] < min:
                      return inner(LS1[1:], LS1[0], max)
                      else:
                      return inner(LS1[1:], min, max)
                      try:
                      return inner(LS[1:], LS[0], LS[0])
                      except IndexError:
                      print("Oops! That was no valid input. Try again...")

                      findminmax([2,1,4,9,4.5])
                      # => (1, 9)

                      findminmax([2])
                      # => (2, 2)

                      findminmax('txwwadga')
                      # => ('a', 'x')

                      findminmax('t')
                      # => ('t', 't')

                      findminmax() # empty list
                      # => Oops! That was no valid input. Try again...

                      findminmax('') # empty string
                      # => Oops! That was no valid input. Try again...





                      share|improve this answer























                      • I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
                        – user633183
                        Nov 7 at 15:22










                      • You're inner() nested function checks if L1 is empty but your outer findminmax() fails to check if L is empty so dies with IndexError: list index out of range
                        – cdlane
                        Nov 7 at 18:27










                      • @cdlane thanks for your valuable comment. I learnt something important from you. The answer is updated now. If you have better ideas, feel free to edit it
                        – englealuze
                        Nov 8 at 9:01















                      up vote
                      1
                      down vote













                      To find either max or min separately is easy. What is difficult is to find both max and min through recursive calls. Tail recursion is exactly for this (maintain and update status of variables through recursive calls) and is usually straightforward to write:



                      def findminmax(L):
                      def inner(L1, min, max):
                      if L1 == :
                      return (min, max)
                      elif L1[0] > max:
                      return inner(L1[1:], min, L1[0])
                      elif L1[0] < min:
                      return inner(L1[1:], L1[0], max)
                      else:
                      return inner(L1[1:], min, max)
                      return inner(L[1:], L[0], L[0])

                      findminmax([2,1,4,9,4.5])
                      # => (1, 9)


                      No need for assignment and fancy list indexing. Only the most basic list operation is needed. The recursion structure is clear and very standard (obviously see base case, reduction and function recursive call) and the code is also very readable as plain English.



                      Update



                      A little modification to handle the string input and empty list or string input:



                      def findminmax(LS):
                      def inner(LS1, min, max):
                      if not LS1:
                      return (min, max)
                      elif LS1[0] > max:
                      return inner(LS1[1:], min, LS1[0])
                      elif LS1[0] < min:
                      return inner(LS1[1:], LS1[0], max)
                      else:
                      return inner(LS1[1:], min, max)
                      try:
                      return inner(LS[1:], LS[0], LS[0])
                      except IndexError:
                      print("Oops! That was no valid input. Try again...")

                      findminmax([2,1,4,9,4.5])
                      # => (1, 9)

                      findminmax([2])
                      # => (2, 2)

                      findminmax('txwwadga')
                      # => ('a', 'x')

                      findminmax('t')
                      # => ('t', 't')

                      findminmax() # empty list
                      # => Oops! That was no valid input. Try again...

                      findminmax('') # empty string
                      # => Oops! That was no valid input. Try again...





                      share|improve this answer























                      • I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
                        – user633183
                        Nov 7 at 15:22










                      • You're inner() nested function checks if L1 is empty but your outer findminmax() fails to check if L is empty so dies with IndexError: list index out of range
                        – cdlane
                        Nov 7 at 18:27










                      • @cdlane thanks for your valuable comment. I learnt something important from you. The answer is updated now. If you have better ideas, feel free to edit it
                        – englealuze
                        Nov 8 at 9:01













                      up vote
                      1
                      down vote










                      up vote
                      1
                      down vote









                      To find either max or min separately is easy. What is difficult is to find both max and min through recursive calls. Tail recursion is exactly for this (maintain and update status of variables through recursive calls) and is usually straightforward to write:



                      def findminmax(L):
                      def inner(L1, min, max):
                      if L1 == :
                      return (min, max)
                      elif L1[0] > max:
                      return inner(L1[1:], min, L1[0])
                      elif L1[0] < min:
                      return inner(L1[1:], L1[0], max)
                      else:
                      return inner(L1[1:], min, max)
                      return inner(L[1:], L[0], L[0])

                      findminmax([2,1,4,9,4.5])
                      # => (1, 9)


                      No need for assignment and fancy list indexing. Only the most basic list operation is needed. The recursion structure is clear and very standard (obviously see base case, reduction and function recursive call) and the code is also very readable as plain English.



                      Update



                      A little modification to handle the string input and empty list or string input:



                      def findminmax(LS):
                      def inner(LS1, min, max):
                      if not LS1:
                      return (min, max)
                      elif LS1[0] > max:
                      return inner(LS1[1:], min, LS1[0])
                      elif LS1[0] < min:
                      return inner(LS1[1:], LS1[0], max)
                      else:
                      return inner(LS1[1:], min, max)
                      try:
                      return inner(LS[1:], LS[0], LS[0])
                      except IndexError:
                      print("Oops! That was no valid input. Try again...")

                      findminmax([2,1,4,9,4.5])
                      # => (1, 9)

                      findminmax([2])
                      # => (2, 2)

                      findminmax('txwwadga')
                      # => ('a', 'x')

                      findminmax('t')
                      # => ('t', 't')

                      findminmax() # empty list
                      # => Oops! That was no valid input. Try again...

                      findminmax('') # empty string
                      # => Oops! That was no valid input. Try again...





                      share|improve this answer














                      To find either max or min separately is easy. What is difficult is to find both max and min through recursive calls. Tail recursion is exactly for this (maintain and update status of variables through recursive calls) and is usually straightforward to write:



                      def findminmax(L):
                      def inner(L1, min, max):
                      if L1 == :
                      return (min, max)
                      elif L1[0] > max:
                      return inner(L1[1:], min, L1[0])
                      elif L1[0] < min:
                      return inner(L1[1:], L1[0], max)
                      else:
                      return inner(L1[1:], min, max)
                      return inner(L[1:], L[0], L[0])

                      findminmax([2,1,4,9,4.5])
                      # => (1, 9)


                      No need for assignment and fancy list indexing. Only the most basic list operation is needed. The recursion structure is clear and very standard (obviously see base case, reduction and function recursive call) and the code is also very readable as plain English.



                      Update



                      A little modification to handle the string input and empty list or string input:



                      def findminmax(LS):
                      def inner(LS1, min, max):
                      if not LS1:
                      return (min, max)
                      elif LS1[0] > max:
                      return inner(LS1[1:], min, LS1[0])
                      elif LS1[0] < min:
                      return inner(LS1[1:], LS1[0], max)
                      else:
                      return inner(LS1[1:], min, max)
                      try:
                      return inner(LS[1:], LS[0], LS[0])
                      except IndexError:
                      print("Oops! That was no valid input. Try again...")

                      findminmax([2,1,4,9,4.5])
                      # => (1, 9)

                      findminmax([2])
                      # => (2, 2)

                      findminmax('txwwadga')
                      # => ('a', 'x')

                      findminmax('t')
                      # => ('t', 't')

                      findminmax() # empty list
                      # => Oops! That was no valid input. Try again...

                      findminmax('') # empty string
                      # => Oops! That was no valid input. Try again...






                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 8 at 9:00

























                      answered Nov 7 at 12:24









                      englealuze

                      741512




                      741512












                      • I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
                        – user633183
                        Nov 7 at 15:22










                      • You're inner() nested function checks if L1 is empty but your outer findminmax() fails to check if L is empty so dies with IndexError: list index out of range
                        – cdlane
                        Nov 7 at 18:27










                      • @cdlane thanks for your valuable comment. I learnt something important from you. The answer is updated now. If you have better ideas, feel free to edit it
                        – englealuze
                        Nov 8 at 9:01


















                      • I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
                        – user633183
                        Nov 7 at 15:22










                      • You're inner() nested function checks if L1 is empty but your outer findminmax() fails to check if L is empty so dies with IndexError: list index out of range
                        – cdlane
                        Nov 7 at 18:27










                      • @cdlane thanks for your valuable comment. I learnt something important from you. The answer is updated now. If you have better ideas, feel free to edit it
                        – englealuze
                        Nov 8 at 9:01
















                      I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
                      – user633183
                      Nov 7 at 15:22




                      I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
                      – user633183
                      Nov 7 at 15:22












                      You're inner() nested function checks if L1 is empty but your outer findminmax() fails to check if L is empty so dies with IndexError: list index out of range
                      – cdlane
                      Nov 7 at 18:27




                      You're inner() nested function checks if L1 is empty but your outer findminmax() fails to check if L is empty so dies with IndexError: list index out of range
                      – cdlane
                      Nov 7 at 18:27












                      @cdlane thanks for your valuable comment. I learnt something important from you. The answer is updated now. If you have better ideas, feel free to edit it
                      – englealuze
                      Nov 8 at 9:01




                      @cdlane thanks for your valuable comment. I learnt something important from you. The answer is updated now. If you have better ideas, feel free to edit it
                      – englealuze
                      Nov 8 at 9:01










                      up vote
                      0
                      down vote













                      You can add another def (read comments):



                      def f(l):
                      return findmin(l)+findmax(l) # Also you can do: `(findmin(l)[0],findmax(l)[0])`


                      Now to call it, do:



                      print(f([2,1,4,9,4.5]))


                      Output would be:



                      (1, 9)





                      share|improve this answer

























                        up vote
                        0
                        down vote













                        You can add another def (read comments):



                        def f(l):
                        return findmin(l)+findmax(l) # Also you can do: `(findmin(l)[0],findmax(l)[0])`


                        Now to call it, do:



                        print(f([2,1,4,9,4.5]))


                        Output would be:



                        (1, 9)





                        share|improve this answer























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          You can add another def (read comments):



                          def f(l):
                          return findmin(l)+findmax(l) # Also you can do: `(findmin(l)[0],findmax(l)[0])`


                          Now to call it, do:



                          print(f([2,1,4,9,4.5]))


                          Output would be:



                          (1, 9)





                          share|improve this answer












                          You can add another def (read comments):



                          def f(l):
                          return findmin(l)+findmax(l) # Also you can do: `(findmin(l)[0],findmax(l)[0])`


                          Now to call it, do:



                          print(f([2,1,4,9,4.5]))


                          Output would be:



                          (1, 9)






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 7 at 0:59









                          U9-Forward

                          9,9842834




                          9,9842834






















                              up vote
                              0
                              down vote













                              You're definitely over-complicating the recursive function. Both minimum and maximum can be returned in a tuple with the following recursive code.



                              my_list = [2,1,4,9,4.5]

                              def recursive_min_max(list_a, pos, biggest, smallest):
                              if pos != len(list_a) - 1:
                              biggest_new = list_a[pos] if biggest == None else list_a[pos] if list_a[pos] > biggest else biggest
                              smallest_new = list_a[pos] if smallest == None else list_a[pos] if list_a[pos] < smallest else smallest
                              return recursive_min_max(list_a, pos + 1, biggest_new, smallest_new)
                              return (biggest,smallest)


                              print(recursive_min_max(my_list, 0, None, None))


                              At each step, the current list item is being compared to the current biggest and smallest elements. If they are bigger/smaller, the current value replaces them.






                              share|improve this answer

















                              • 2




                                If you apply this solution to the list [1], you should get (1, 1) but instead you get (None, None). If you apply this solution to the empty list, it fails with IndexError: list index out of range,
                                – cdlane
                                Nov 7 at 8:09










                              • There seems to be something wrong in the logic. If I set my_list = [112, 97], I get back (112, 112) as a result. Changing if pos != len(list_a) - 1 to simply if pos < len(list_a) seems to help. Also return (biggest,smallest) is backward.
                                – cdlane
                                Nov 7 at 8:47















                              up vote
                              0
                              down vote













                              You're definitely over-complicating the recursive function. Both minimum and maximum can be returned in a tuple with the following recursive code.



                              my_list = [2,1,4,9,4.5]

                              def recursive_min_max(list_a, pos, biggest, smallest):
                              if pos != len(list_a) - 1:
                              biggest_new = list_a[pos] if biggest == None else list_a[pos] if list_a[pos] > biggest else biggest
                              smallest_new = list_a[pos] if smallest == None else list_a[pos] if list_a[pos] < smallest else smallest
                              return recursive_min_max(list_a, pos + 1, biggest_new, smallest_new)
                              return (biggest,smallest)


                              print(recursive_min_max(my_list, 0, None, None))


                              At each step, the current list item is being compared to the current biggest and smallest elements. If they are bigger/smaller, the current value replaces them.






                              share|improve this answer

















                              • 2




                                If you apply this solution to the list [1], you should get (1, 1) but instead you get (None, None). If you apply this solution to the empty list, it fails with IndexError: list index out of range,
                                – cdlane
                                Nov 7 at 8:09










                              • There seems to be something wrong in the logic. If I set my_list = [112, 97], I get back (112, 112) as a result. Changing if pos != len(list_a) - 1 to simply if pos < len(list_a) seems to help. Also return (biggest,smallest) is backward.
                                – cdlane
                                Nov 7 at 8:47













                              up vote
                              0
                              down vote










                              up vote
                              0
                              down vote









                              You're definitely over-complicating the recursive function. Both minimum and maximum can be returned in a tuple with the following recursive code.



                              my_list = [2,1,4,9,4.5]

                              def recursive_min_max(list_a, pos, biggest, smallest):
                              if pos != len(list_a) - 1:
                              biggest_new = list_a[pos] if biggest == None else list_a[pos] if list_a[pos] > biggest else biggest
                              smallest_new = list_a[pos] if smallest == None else list_a[pos] if list_a[pos] < smallest else smallest
                              return recursive_min_max(list_a, pos + 1, biggest_new, smallest_new)
                              return (biggest,smallest)


                              print(recursive_min_max(my_list, 0, None, None))


                              At each step, the current list item is being compared to the current biggest and smallest elements. If they are bigger/smaller, the current value replaces them.






                              share|improve this answer












                              You're definitely over-complicating the recursive function. Both minimum and maximum can be returned in a tuple with the following recursive code.



                              my_list = [2,1,4,9,4.5]

                              def recursive_min_max(list_a, pos, biggest, smallest):
                              if pos != len(list_a) - 1:
                              biggest_new = list_a[pos] if biggest == None else list_a[pos] if list_a[pos] > biggest else biggest
                              smallest_new = list_a[pos] if smallest == None else list_a[pos] if list_a[pos] < smallest else smallest
                              return recursive_min_max(list_a, pos + 1, biggest_new, smallest_new)
                              return (biggest,smallest)


                              print(recursive_min_max(my_list, 0, None, None))


                              At each step, the current list item is being compared to the current biggest and smallest elements. If they are bigger/smaller, the current value replaces them.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 7 at 1:15









                              PL200

                              535212




                              535212








                              • 2




                                If you apply this solution to the list [1], you should get (1, 1) but instead you get (None, None). If you apply this solution to the empty list, it fails with IndexError: list index out of range,
                                – cdlane
                                Nov 7 at 8:09










                              • There seems to be something wrong in the logic. If I set my_list = [112, 97], I get back (112, 112) as a result. Changing if pos != len(list_a) - 1 to simply if pos < len(list_a) seems to help. Also return (biggest,smallest) is backward.
                                – cdlane
                                Nov 7 at 8:47














                              • 2




                                If you apply this solution to the list [1], you should get (1, 1) but instead you get (None, None). If you apply this solution to the empty list, it fails with IndexError: list index out of range,
                                – cdlane
                                Nov 7 at 8:09










                              • There seems to be something wrong in the logic. If I set my_list = [112, 97], I get back (112, 112) as a result. Changing if pos != len(list_a) - 1 to simply if pos < len(list_a) seems to help. Also return (biggest,smallest) is backward.
                                – cdlane
                                Nov 7 at 8:47








                              2




                              2




                              If you apply this solution to the list [1], you should get (1, 1) but instead you get (None, None). If you apply this solution to the empty list, it fails with IndexError: list index out of range,
                              – cdlane
                              Nov 7 at 8:09




                              If you apply this solution to the list [1], you should get (1, 1) but instead you get (None, None). If you apply this solution to the empty list, it fails with IndexError: list index out of range,
                              – cdlane
                              Nov 7 at 8:09












                              There seems to be something wrong in the logic. If I set my_list = [112, 97], I get back (112, 112) as a result. Changing if pos != len(list_a) - 1 to simply if pos < len(list_a) seems to help. Also return (biggest,smallest) is backward.
                              – cdlane
                              Nov 7 at 8:47




                              There seems to be something wrong in the logic. If I set my_list = [112, 97], I get back (112, 112) as a result. Changing if pos != len(list_a) - 1 to simply if pos < len(list_a) seems to help. Also return (biggest,smallest) is backward.
                              – cdlane
                              Nov 7 at 8:47


















                               

                              draft saved


                              draft discarded



















































                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53182287%2fpython-minmax-using-only-recursion%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              這個網誌中的熱門文章

                              Xamarin.form Move up view when keyboard appear

                              Post-Redirect-Get with Spring WebFlux and Thymeleaf

                              Anylogic : not able to use stopDelay()