Returning largest product of longest subsequence between min and max This function returns the largest product of all elements of a list between the leftmost and rightmost min and max elements. Is there more readable and maybe compact way to rewrite the elif chain in this code:
from operator import mul
from functools import reduce

prod = lambda iterable: reduce(mul, iterable, 1)

def prod_between_min_and_max(arr):
    l_min, r_max = arr.index(min(arr)), len(arr)-1 - arr[::-1].index(max(arr))
    l_max, r_min = arr.index(max(arr)), len(arr)-1 - arr[::-1].index(min(arr))
    if len(range(l_min, r_max+1)) &gt; len(range(l_max, r_min+1)):
        sl = slice(l_min, r_max+1)
    elif len(range(l_min, r_max+1)) &lt; len(range(l_max, r_min+1)):
        sl = slice(l_max, r_min+1)
    elif prod(arr[l_min:r_max+1]) &gt;= prod(arr[l_max:r_min+1]):
        sl = slice(l_min, r_max+1) 
    else:
        sl = slice(l_max, r_min+1)
    return prod(arr[sl])    

than this:
from operator import mul
from functools import reduce

cmp = lambda a, b: (a &gt; b) - (a &lt; b)
prod = lambda iterable: reduce(mul, iterable, 1)

def prod_between_min_and_max(arr):
    l_min, r_max = arr.index(min(arr)), len(arr)-1 - arr[::-1].index(max(arr))
    l_max, r_min = arr.index(max(arr)), len(arr)-1 - arr[::-1].index(min(arr))
    sl = [
        [
            slice(l_max, r_min+1),
            slice(l_min, r_max+1)
        ][
            prod(arr[l_min:r_max+1]) &gt;= prod(arr[l_max:r_min+1])
        ], 
        slice(l_min, r_max+1), 
        slice(l_max, r_min+1)
    ][
        cmp(len(range(l_min, r_max+1)), len(range(l_max, r_min+1)))
    ]
    return prod(arr[sl])

Note: The code works in both Python 2 and Python 3.
The second example is terrible, don't use it.



You assign sl to either (l_min, r_max) or (l_max, r_min), and so you just need to change your ifs to become one if and an else.

First off len(range(l_min, r_max+1)) is the same as r_max+1 - l_min, and there's no need for the +1 if both sides have it. So your first if could become: r_max - l_min &gt; r_min - l_max.

To merge the first and third, you should check it's the first, or explicitly check it's not the second and is the third. And so you can get:

def prod_between_min_and_max(arr):
    l_min = arr.index(min(arr))
    l_max = arr.index(max(arr))
    r_max = len(arr)-1 - arr[::-1].index(max(arr))
    r_min = len(arr)-1 - arr[::-1].index(min(arr))
    if (r_max - l_min &gt; r_min - l_max
      or (r_max - l_min == r_min - l_max
          and prod(arr[l_min:r_max+1]) &gt;= prod(arr[l_max:r_min+1]))):
        sl = (l_min, r_max)
    else:
        sl = (l_max, r_min)
    return prod(arr[slice(sl[0], sl[1]+1)])


This reminds me of FizzBuzz, as there doesn't seem to be a 'nice' solution.