3

I want to take in a list with nested lists. Then print the highest value of index 0 or 2 in the list and the lowest value of index 0 or 2, through using recursion.

This is what I got so far:

lst = [1, 5, [7, 10, []]]

def high_low(my_list):
    new_lst = []
    if not my_list:
        print max(new_lst)
        print min(new_lst)
    elif isinstance(my_list[0], int):
        return new_lst.append(my_list[0]) + high_low(my_list[2:])
    elif isinstance(my_list[0], list):
        return new_lst.append(max(my_list[0])) + high_low(my_list[2:])

This is where I get stuck, as I don't know how to get the highest and lowest value from a nested list and then append it to the new empty list. For example this is what I want the output to look like:

>>> print_tree(lst)
10 
1

3 Answers3

1

Here's one possibility to write the code with only one pass, no need for external library or python's min/max:

def high_low(list_or_number):
    if isinstance(list_or_number, list):
        current_min = float('inf')
        current_max = float('-inf')
        for x in list_or_number:
            x_max, x_min = high_low(x)
            if x_max > current_max:
                current_max = x_max
            if x_min < current_min:
                current_min = x_min
        return (current_max, current_min)
    else:
        return (list_or_number, list_or_number)

As an example:

>>> high_low([1, 5, [7, 10, [[12, 16], -10]]])
(16, -10)
>>> high_low(3)
(3, 3)
>>> high_low([3,4,5])
(5, 3)
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
0

this can be achieved using a similar & classic problem solving (Flatten an irregular list of lists), no need to reinvent the wheel, just use some working method & post-process:

Flatten the list of lists, then take min & max of it.

import collections

def flatten(l):   # function copied from the link above
    for el in l:
        if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
            yield from flatten(el)
        else:
            yield el

lst = [1, 5, [7, 10, []]]

new_list = list(flatten(lst))  # create a list cos we'll be iterating twice on it
print(max(new_list))
print(min(new_list))

result

10
1

with one iteration with a manual loop:

min_value = None
max_value = None
for v in flatten(lst):
    if min_value is None or v < min_value:
        min_value = v
    if max_value is None or v > max_value:
        max_value = v

print(min_value)
print(max_value)

the flatten method is nice because it doesn't create temporary list elements so no unneccesary memory allocations.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
-1

You can use the following recursive function that returns the maximum and minimum among the items in the current list and the maximum and minimum of the sublists:

def high_low(l):
    try:
        l.extend(high_low(l.pop()))
    except AttributeError:
        return [l]
    except IndexError:
        return []
    return max(l), min(l)

so that:

lst = [1, 5, [7, 10, []]]
print(high_low(lst))

outputs:

(10, 1)
blhsing
  • 91,368
  • 6
  • 71
  • 106
  • Looks nice. However I want it to work for different cases and not just one. –  Sep 30 '18 at 10:40
  • Okay, I had trouble understanding how it works. The thing is, it doesn't. – Eric Duminil Sep 30 '18 at 10:44
  • @Blueshirt In which cases does it not work? Can you update your question with such cases? – blhsing Sep 30 '18 at 12:58
  • `print(high_low([3,5]))` or `print(high_low([3,[5, 7]]))` for example. – Eric Duminil Sep 30 '18 at 13:50
  • @EricDuminil I see. I've fixed it for those cases then. – blhsing Sep 30 '18 at 14:38
  • @Blueshirt Does my updated answer for EricDuminil fix your different cases as well? – blhsing Sep 30 '18 at 14:50
  • It still doesn't seem to work : `high_low([[3,5],7])` returns `([3, 5], 7)` – Eric Duminil Sep 30 '18 at 16:26
  • @EricDuminil I'm fairly sure that all of the OP's input lists are only nested at the last index of a parent list, as evident by his sample input as well as his attempt to perform recursion on a slice of index 2 to the end of a list in his code. – blhsing Sep 30 '18 at 16:35
  • It could be. But that would make for a suprising/buggy method. It's not so hard to write a method which works for any nested list. – Eric Duminil Sep 30 '18 at 16:38
  • @EricDuminil If that's the data model the OP is deciding on using, then there's nothing wrong to implement methods around that exact data model. But then again, I can hardly imagine a case where the OP's data model can be meaningfully useful. – blhsing Sep 30 '18 at 16:42