user15107839
user15107839

Reputation: 17

Recursive division over a list

I'm looking to divide every element of an list recursivly like this.

a_list = [1, 2, 3, 4, 5] so the returns would be 1/(2/(3/(4/5)))

def c(y):

    if not y:
        return 1  # division by 1 don't matter

    return c(y[1:])[0] / c(y[2:])[1]  # Not allowed

Upvotes: 0

Views: 135

Answers (3)

Alain T.
Alain T.

Reputation: 42143

Recursively, you can divide the first element by the result of recursing with the rest:

def recDiv(a):
    return a[0] / recDiv(a[1:]) if a else 1

a_list = [1, 2, 3, 4, 5]

print(recDiv(a_list)) # 1.875

Alternatively you could use the prod() function from math and apply a power of 1 or -1 depending on items being at even or odd positions.

a_list = [1, 2, 3, 4, 5]

from math import prod

result = prod(n**[1,-1][i&1] for i,n in enumerate(a_list))

print(result) # 1.875

Which would translate into a regular loop like this:

result = 1
for i,n in enumerate(a_list):
    result *= n ** [1,-1][i&1]  # result *= 1/n if i%2 else n
    
print(result) # 1.875

Upvotes: 1

Kelly Bundy
Kelly Bundy

Reputation: 27588

Yours fixed and some mostly non-recursive alternatives (@9769953's fixed, and some by me):

for y in [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6]:
    print(y)

    def c(y):
        if not y:
            return 1
        return y[0] / c(y[1:])
    print(c(y))

    from functools import reduce
    print(reduce(lambda a, b: b / a, reversed(y)))

    from math import prod
    print(prod(y[::2]) / prod(y[1::2]))

    z = 1
    for x in reversed(y):
        z = x / z
    print(z)

    def d(y):
        y = iter(y)
        try:
            return next(y) / d(y)
        except StopIteration:
            return 1
    print(d(y))

    print()

Output showing the two test cases and the results of the five solutions (Try it online!):

[1, 2, 3, 4, 5]
1.875
1.875
1.875
1.875
1.875

[1, 2, 3, 4, 5, 6]
0.3125
0.3125
0.3125
0.3125
0.3125

Upvotes: 2

Richard Ambler
Richard Ambler

Reputation: 5030

You could use simple recursion over the indices. For example:

a_list = [i + 1 for i in range(6)]


def divide(index: int = 0) -> float:
    if index == len(a_list):
        return 1
    return a_list[index] / divide(index + 1)


print(divide()) # 0.3125

Or, an equivalent implementation but with the list passed as an argument:

def divide(a_list: list, index: int = 0) -> float:
    if index == len(a_list):
        return 1
    return a_list[index] / divide(a_list, index + 1)

a_list = [i + 1 for i in range(6)]
print(divide(a_list)) # 0.3125

Or, using your original approach:

def divide(a_list: list) -> float:
    if not a_list:
        return 1
    n, *d = a_list
    return n / divide(d)


a_list = [i + 1 for i in range(6)]
print(divide(a_list)) # 0.3125

Upvotes: 0

Related Questions