2

I was working on a recursion algorithm and needed some help, so I came here and did some digging. What I found works for what I wanted it to do (Link: python minmax using only recursion), but I don't understand why and how it works. Here is the code:

def minMax(A,n):
if A:
    header = A[0]
    tailend = A[1:]

    if tailend != []:
        minimum, maximum = minMax(tailend,n-1)
        return [header, minimum][minimum < header], [header, maximum][maximum > header]

    return header, header
return A

intlist = [30, 50, 20, 70, 10, 80, 25, 100, 60, 40]
print(minMax(intlist,len(intlist)))

What I dont understand is this piece: return [header, minimum][minimum < header], [header, maximum][maximum > header] How do the brackets work? As far as I know, brackets are used for slicing, lists, indexing, and the sort. But here, it appears that there are some sort of keywords going on from behind the scenes and I just can't figure it out. Any help would be appreciated.

Jonah
  • 23
  • 4
  • 4
    First bracket defines a list of two items, second bracket is an item access with a boolean value which also evaluates to 0 for False or 1 for True. – Michael Butscher Jan 25 '22 at 04:24
  • 1
    Also: returning the lists with a comma between them returns them as a tuple. – csjh Jan 25 '22 at 04:26
  • 1
    It is a silly and confusing way to write `if minimum < header: return minimum else: return header` (first part before the comma only, similar after the comma of course). – 9769953 Jan 25 '22 at 04:32
  • @9769953 I'm an amateur programmer and I always wonder if those "silly ways to" write code are just that or something usefull to up-speed your code, save memory, etc... – José Chamorro Jan 25 '22 at 04:36
  • 1
    @JoséChamorro Sometimes, they possible are. Here, they are probably meant as a shortcut, instead of having to write an if-else statement. But, certainly with Python, I think attempting to try and speed-up code or save memory in such an obtuse way is incredibly unhelpful (and for languages where it does matter, there are likely either better constructs to achieve this, or the compiler/interpreter will be smarter than the programmer). – 9769953 Jan 25 '22 at 07:14
  • @JoséChamorro in this case, no. It unnecessarily creates a list and indexes into the list, and while it doesn't make a big difference here, it will always evaluate both options and has no chance of short-circuiting. It is unidiomatic (although very long ago before conditional expressions you'd see it more often), and the person who wrote this was trying to keep their code short – juanpa.arrivillaga Jan 25 '22 at 07:46

3 Answers3

3

You have a list [] that is being subscripted [1,2,3][0]

If you run minimun < header and both minumun and header are well defined, the output will be a boolean True or False.

Now, in Python:

0=False
1=True

That's how it is.

So you are getting either element 0 or 1 of your list.

As pointed by @csjh, your 'return' will, interprete a serie of values separated by comas and with no further specification, as a tuple.

So, you are getting either element 0 or 1 of each of your lists and you are getting that info as a tuple of len 2:

(element_1,element_2)
José Chamorro
  • 497
  • 1
  • 6
  • 21
2

Not an explanation, but a somewhat more Python (but still obtuse) way to write this as a one-liner is:

return header if minimum > header else minimum, header if maximum < header else maximum

which uses Python's variant of the ternary if-else expression.

To be more explicit, you could simply write

if minimum > header:
    a = header
else:
    a = minimum

if maximum < header:
    b = header
else:
    b = maximum

return (a, b)

or with the ternary expression:

a = header if minimum > header else minimum
b = header if maximum < header else maximum
return (a, b)

which in my opinion keeps the code reasonably short, while still being much clearer than the original.


Of course, the above is going all wrong about, but stays perhaps closer to the original statement. Here is what you (really) should do:

return min(minimum, header), max(maximum, header)

It shows the actual intent, and is far shorter than any other way of writing this. (It may ignore the actual purpose of the exercise, so it's a bit of out of context.)

9769953
  • 10,344
  • 3
  • 26
  • 37
0

[minimum < header] is the index for the list. Since indexes are supposed to be integers, [minimum < header] gets coerced to an integer. False goes to 0 and True goes to 1. So if minimum is less than header, minimum gets returned, because it is the element at index 1. Otherwise, header gets returned. This is a fancy way of getting min([header, minimum]). I'm not sure whether the person writing this was just showing off or forgot about min.

Acccumulation
  • 3,491
  • 1
  • 8
  • 12