python minmax using only recursion
up vote
1
down vote
favorite
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
add a comment |
up vote
1
down vote
favorite
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
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
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
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
python recursion minmax
asked Nov 7 at 0:57
1231231231231
391
391
add a comment |
add a comment |
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.
add a comment |
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
You implementedminmax()
by callingmin()
andmax()
which the OP said couldn't be used! If we can simply callmin()
andmax()
, 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 throughx
twice. This algorithm does not do that. Simplemin
andmax
definitions added.
– user633183
Nov 7 at 18:59
add a comment |
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...
I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
– user633183
Nov 7 at 15:22
You'reinner()
nested function checks ifL1
is empty but your outerfindminmax()
fails to check ifL
is empty so dies withIndexError: 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
add a comment |
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)
add a comment |
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.
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 withIndexError: list index out of range
,
– cdlane
Nov 7 at 8:09
There seems to be something wrong in the logic. If I setmy_list = [112, 97]
, I get back(112, 112)
as a result. Changingif pos != len(list_a) - 1
to simplyif pos < len(list_a)
seems to help. Alsoreturn (biggest,smallest)
is backward.
– cdlane
Nov 7 at 8:47
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
edited Nov 7 at 18:30
answered Nov 7 at 8:07
cdlane
16.5k21042
16.5k21042
add a comment |
add a comment |
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
You implementedminmax()
by callingmin()
andmax()
which the OP said couldn't be used! If we can simply callmin()
andmax()
, 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 throughx
twice. This algorithm does not do that. Simplemin
andmax
definitions added.
– user633183
Nov 7 at 18:59
add a comment |
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
You implementedminmax()
by callingmin()
andmax()
which the OP said couldn't be used! If we can simply callmin()
andmax()
, 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 throughx
twice. This algorithm does not do that. Simplemin
andmax
definitions added.
– user633183
Nov 7 at 18:59
add a comment |
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
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
edited Nov 7 at 18:58
answered Nov 7 at 15:18
user633183
66.7k21130172
66.7k21130172
You implementedminmax()
by callingmin()
andmax()
which the OP said couldn't be used! If we can simply callmin()
andmax()
, 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 throughx
twice. This algorithm does not do that. Simplemin
andmax
definitions added.
– user633183
Nov 7 at 18:59
add a comment |
You implementedminmax()
by callingmin()
andmax()
which the OP said couldn't be used! If we can simply callmin()
andmax()
, 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 throughx
twice. This algorithm does not do that. Simplemin
andmax
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
add a comment |
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...
I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
– user633183
Nov 7 at 15:22
You'reinner()
nested function checks ifL1
is empty but your outerfindminmax()
fails to check ifL
is empty so dies withIndexError: 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
add a comment |
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...
I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
– user633183
Nov 7 at 15:22
You'reinner()
nested function checks ifL1
is empty but your outerfindminmax()
fails to check ifL
is empty so dies withIndexError: 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
add a comment |
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...
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...
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'reinner()
nested function checks ifL1
is empty but your outerfindminmax()
fails to check ifL
is empty so dies withIndexError: 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
add a comment |
I'm enjoying reading your answers. This is a very nice solution. Only simple basic operations used.
– user633183
Nov 7 at 15:22
You'reinner()
nested function checks ifL1
is empty but your outerfindminmax()
fails to check ifL
is empty so dies withIndexError: 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
add a comment |
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)
add a comment |
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)
add a comment |
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)
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)
answered Nov 7 at 0:59
U9-Forward
9,9842834
9,9842834
add a comment |
add a comment |
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.
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 withIndexError: list index out of range
,
– cdlane
Nov 7 at 8:09
There seems to be something wrong in the logic. If I setmy_list = [112, 97]
, I get back(112, 112)
as a result. Changingif pos != len(list_a) - 1
to simplyif pos < len(list_a)
seems to help. Alsoreturn (biggest,smallest)
is backward.
– cdlane
Nov 7 at 8:47
add a comment |
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.
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 withIndexError: list index out of range
,
– cdlane
Nov 7 at 8:09
There seems to be something wrong in the logic. If I setmy_list = [112, 97]
, I get back(112, 112)
as a result. Changingif pos != len(list_a) - 1
to simplyif pos < len(list_a)
seems to help. Alsoreturn (biggest,smallest)
is backward.
– cdlane
Nov 7 at 8:47
add a comment |
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.
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.
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 withIndexError: list index out of range
,
– cdlane
Nov 7 at 8:09
There seems to be something wrong in the logic. If I setmy_list = [112, 97]
, I get back(112, 112)
as a result. Changingif pos != len(list_a) - 1
to simplyif pos < len(list_a)
seems to help. Alsoreturn (biggest,smallest)
is backward.
– cdlane
Nov 7 at 8:47
add a comment |
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 withIndexError: list index out of range
,
– cdlane
Nov 7 at 8:09
There seems to be something wrong in the logic. If I setmy_list = [112, 97]
, I get back(112, 112)
as a result. Changingif pos != len(list_a) - 1
to simplyif pos < len(list_a)
seems to help. Alsoreturn (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
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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