I made a few recursive functions for learning purposes which do a variety of tasks. Here is my current and functioning code:
def separate(p,l):
''' recursive function when is passed a predicate and a list returns a 2-tuple
whose 0 index is a list of all the values in the argument list for which the
predicate returns True,and whose 1 index is a list of all the values in the
argument list for which the predicate returns False.'''
if len(l) == 0:
return ([],[])
else:
(true_list, false_list) = separate(p,l[1:])
if p(l[0]):
return ([l[0]] + true_list, false_list)
else:
return (true_list, [l[0]] + false_list)
def is_sorted(s):
''' recursive function when passed a list returns a bool telling whether or not
the values in the list are in non-descending order: lowest to highest allowing
repetitions. '''
if len(s) <= 1:
return True
elif s[0] < s[1]:
return is_sorted(s[1:])
else:
return False
def sort(l):
''' recursive function when passed a list; it returns a new list (not mutating
the passed one) with every value in the original list, but ordered in non-
descending order. '''
if len(l) == 0:
return []
else:
(before, after) = separate(lambda i: i < l[0], l[1:])
return sort(before) + [l[0]] + sort(after)
def compare(a,b):
''' a recursive function when is passed two str arguments; it returns one of
three str values: '<’, '=’, or '>’ which indicates the relationship between the
first and second parameter.'''
if a == '' and b == '':
return '='
if a == '' and b != '':
return '<'
if a != '' and b == '':
return '>'
if a[0] > b[0]:
return '>'
if a[0] < b[0]:
return '<'
else:
return compare(a[1:],b[1:])
Is there a way to write these recursive functions in a cleaner/concise way? Any help would be great.
2 Answers 2
is_sorted()
does not behave as described or as expected. It requires elements to be strictly increasing rather than non-descending.
The implementation and docstring could be shorter as well.
def is_sorted(list):
"""Recursively checks if the elements in the list are in non-descending order."""
return len(list) <= 1 or (list[0] <= list[1] and is_sorted(list[1:]))
I'd expect that trimming lists at the end would be more efficient (though the code definitely looks weirder):
def is_sorted(list):
"""Recursively checks if the elements in the list are in non-descending order."""
return len(list) <= 1 or (list[-2] <= list[-1] and is_sorted(list[:-1]))
compare()
has some redundant checks.
Here, I feel that the else
is incongruous. Either rely on the early return
s, or use else
in conjunction with elif
everywhere.
def compare(a,b):
"""Lexicographically compares strings a and b, returning '<', '=', or '>'."""
if a == '' and b == '':
return '='
if a == '':
return '<'
if b == '':
return '>'
if a[0] > b[0]:
return '>'
if a[0] < b[0]:
return '<'
return compare(a[1:], b[1:])
Instead of checking for == ''
, consider checking the length, so that the function can operate on lists as well.
-
\$\begingroup\$ @200_success- using the is_sorted function when I try to do
is_sorted([])
it should return True but it gives me error statingreturn len(list) <= 1 or (list[0] <= list[1] and is_sorted(list[1:])) TypeError: object of type 'type' has no len()
\$\endgroup\$LucyBen– LucyBen2015年02月08日 16:03:22 +00:00Commented Feb 8, 2015 at 16:03 -
\$\begingroup\$ @200_success- compare has the same issue. when I do
compare('','')
it returns < when it should be =.compare('','abc')
return > when it should be <. Similarly, the problem persists if any of the strings compared is empty. Works perfectly fine when comparing with non-empty string args. \$\endgroup\$LucyBen– LucyBen2015年02月08日 16:04:33 +00:00Commented Feb 8, 2015 at 16:04 -
\$\begingroup\$ @LucyBen If you're getting
TypeError: object of type 'type' has no len()
, then you probably missed the detail that I renamed the parameter froms
tolist
. \$\endgroup\$200_success– 200_success2015年02月08日 18:53:10 +00:00Commented Feb 8, 2015 at 18:53 -
\$\begingroup\$ How is it possible that
compare('', '')
returns'<'
? That's handled by the first conditional, which I didn't change at all. \$\endgroup\$200_success– 200_success2015年02月08日 18:54:49 +00:00Commented Feb 8, 2015 at 18:54 -
\$\begingroup\$ @200_success- nm..I made some minor errors in transcribing the code. It works perfectly. Thank you. \$\endgroup\$LucyBen– LucyBen2015年02月08日 19:52:27 +00:00Commented Feb 8, 2015 at 19:52
I recommend you be more consistent in not combining if
followed by a statement sequence ending in return
with an else
(I left out the comments):
def separate(p,l):
if len(l) == 0:
return ([],[])
(true_list, false_list) = separate(p,l[1:])
if p(l[0]):
return ([l[0]] + true_list, false_list)
return (true_list, [l[0]] + false_list)
as you do e.g. in compare()
.
In compare()
I would nest the conditions (arbitrarily based on a
):
def compare(a,b):
if a == '':
if b == '':
return '='
return '<'
if a != '':
if b == '':
return '>'
if a[0] > b[0]:
return '>'
if a[0] < b[0]:
return '<'
return compare(a[1:],b[1:])
That way it is more clear to me that compare()
never ends without a return value.
Your comments should at least use triple double quotes (PEP8) and you should try to conform to PEP 257 (docstring conventions).
-
\$\begingroup\$ @Alice- when I do
compare('','')
it returns < when it should be =.compare('','abc')
return > when it should be <. Similarly, the problem persists if any of the strings compared is empty. Works perfectly fine when comparing with non-empty string args. \$\endgroup\$LucyBen– LucyBen2015年02月08日 16:01:02 +00:00Commented Feb 8, 2015 at 16:01 -
\$\begingroup\$ @LucyBen it doesn't in my test program. Are you sure you are running the right tests? And the same ones that give the correct results on your own code? \$\endgroup\$Alice– Alice2015年02月09日 08:56:43 +00:00Commented Feb 9, 2015 at 8:56
-
\$\begingroup\$ @Alice- I made some minor errors in transcribing the code. It works perfectly. Thank you. any suggestions for sort function?? \$\endgroup\$LucyBen– LucyBen2015年02月09日 09:13:57 +00:00Commented Feb 9, 2015 at 9:13
Explore related questions
See similar questions with these tags.
code_metric()
. It is neither recursive, nor does it reuse your other functions. (I believe you have missed the point of the exercise as well.) \$\endgroup\$