3

Here's everything I got so far... I can't figure what I have done wrong

First my helper function

def max_min(l):

    if isinstance (l[0], list):
        result = max_min(l[0])

    elif len(l) == 2:
        if l[0] < l[1]:
            result = l[0], l[1]
        else:
            result = l[1], l[0]

    else:
        Min, Max = max_min(l[1:])
        if l[0] <= Min:
            result = l[0], Max
        elif l[0] >= Max:
            result = Min, l[0]
        else:
            result = Min, Max

    return result

When tried to do this

l = [6, 3, 7, 5, 5, 2, [3, 2], 1]
print max_min(l)

It gives me (2, 7) which i expected to be (1, 7)

I'm out of ideas... anyone can point me out the directions?

Vincent Savard
  • 34,979
  • 10
  • 68
  • 73
user984343
  • 41
  • 3
  • 8
  • 3
    is using recursion critical to the application? would be much simpler to convert it to a single list then sort it and take the first and last elements – Tom Feb 24 '16 at 16:11
  • Run your code through a debugger and see where it doesn't behave like you expect. – Vincent Savard Feb 24 '16 at 16:14
  • 1
    Is this homework? There's no reason to do this in real code. – Daenyth Feb 24 '16 at 16:23
  • Yea this is homework... well exercise~ We are not allow to go through the list more than once – user984343 Feb 24 '16 at 16:40
  • @user984343. In that case, this is XY problem. There are much better options than recursion. However, points for trying and almost succeeding on your own. – Mad Physicist Feb 24 '16 at 21:01

4 Answers4

4

The moment your program reaches a nested list, it stops evaluating the other elements. The block if isinstance (l[0], list) ensures that if there is a nested list, the remaining elements are not evaluated since Min, Max = max_min(l[1:]) is never called.

You can fix the if block with something like this:

if isinstance (l[0], list):
    Nested_Min, Nested_Max = max_min(l[0])
    Remainder_Min, Remainder_Max = max_min(l[1:])
    Min = Nested_Min if Nested_Min < Remainder_Min else Remainder_Min
    Max = Nested_Max if Nested_Max > Remainder_Max else Remainder_Max
    result = Min, Max

You should also replace the check for if len(l) == 2 with:

if len(l) == 1:
    result = l[0], l[0]

That way your function will not fail for single-element lists. Finally, add something like the following at the beginning:

if not l:
    return ()
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
0

Try this instead:

def min_max(l):
    if isinstance(l, list):
        t = [min_max(v) for v in l]
        return min([m[0] for m in t]), max([m[1] for m in t])
    else:
        return l, l

Sample output:

>>> l = [6, 3, 7, 5, 5, 2, [3, 2], 1]
>>> min_max(l)
(1, 7)
>>>

Note that an empty list or sub-list will cause an error, so you might need to add a check for that if you care about it.

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
0

To expand on my comment you would still need to use recursion to flatten the list as you have a mix of integers and lists, the code would look as follows:

def flatten(l):
    tmp = []
    for i in l:
        if isinstance(i, int):
            tmp.append(i)
        elif isinstance(i, list):
            tmp += flatten(i)
        else:
            raise AttributeError("found unexpected type {t}".format(t=type(i)))
    return tmp
Tom
  • 343
  • 1
  • 13
0

Your recursive function can be simplified and improved at the same time. See the following for details:

#! /usr/bin/env python3


def main():
    array = [6, 3, 7, 5, 5, 2, [3, 2], 1]
    print(sum_min_max(array))


def sum_min_max(array):
    return (lambda a, b: a + b)(*get_min_max(array))


def get_min_max(array, minimum=+float('inf'), maximum=-float('inf')):
    if array:
        head, *tail = array
        if isinstance(head, (list, tuple)):
            minimum, maximum = get_min_max(head, minimum, maximum)
        else:
            if head < minimum:
                minimum = head
            if head > maximum:
                maximum = head
        minimum, maximum = get_min_max(tail, minimum, maximum)
    return minimum, maximum


if __name__ == '__main__':
    main()
Noctis Skytower
  • 21,433
  • 16
  • 79
  • 117