kklaw
kklaw

Reputation: 544

Alternative to global variable

I got a recursive function, which reverses an integer. The reversed Integer can not start with zero, e.g.: 12340 becomes 4321.

res = 0
base = 1


def reverse(n):

    global res
    global base

    if n > 0:
        reverse(n // 10)
        res = res + (n % 10) * base
        base = base * 10

    return res

this code works, but only once and hence I want to get rid of the global variables. I thought of a helper function, inside of the reverse(n) function, but I could not get it to work properly. I have tried for almost an hour and would love to see the solution eventually.

Upvotes: 2

Views: 395

Answers (3)

DarrylG
DarrylG

Reputation: 17176

Example of using a mutable argument to get rid of globals

def reverse(n, res_base = None):
    if res_base is None:
        res_base = [0, 1]    # Use two element list for res, base
                             # res_base[0] -> res
                             # res_base[1] -> base
        
    if n > 0:
        reverse(n // 10, res_base)
        # Update as in original code 
        # but replacing res & base with elements from list res_base
        res_base[0] = (res_base[0] + (n%10)*res_base[1])  # res update
        res_base[1] = res_base[1] * 10                    # base update

    return res_base[0]

Check that it works on multiple runs

print(reverse(12345)) # Output: 54321
print(reverse(6789))  # 9876

Alternative Using Helper Function

def reverse(n):
    def helper(n, res, base):
        if n > 0:
            res, base = helper(n // 10, res, base)
            res = res + (n % 10) * base
            base = base * 10
        return res, base
    
    res, base = helper(n, 0, 1)
    return res
        

print(reverse(12345)) # Output: 54321
print(reverse(6789))  # 9876

Shows Use of Mutable Argument

Use mutable argument removes need to pass update back to parent

def reverse(n):
    def helper(n, res_base):
        if n > 0:
            helper(n//10, res_base)
            res_base[0] += (n%10)*res_base[1]  # Since res_base is mutable, it's parent will see the change in value
            res_base[1] *= 10
    res_base = [0, 1]
    helper(n, res_base)
    return res_base[0]

print(reverse(12345))  # Out: 54321

Upvotes: 1

Laurent B.
Laurent B.

Reputation: 2273

global only on the agg_res variable for the result.

Anyway agg_res is reinitialized at the end of the calculation (no influence on the second re-use)

agg_res=0

def reverse(n, res=0, base=1):
    global agg_res
    ls = len(str(n))
    if n > 0:
        reverse(n // 10, res, base)
        res = res + (n % 10)
        base = base * (10**(ls-1))
        agg_res += res*base
    else :
        agg_res=0

# First time
reverse(5786)
print(agg_res)
# 6875

# Second time
reverse(5786)
print(agg_res)
# 6875

Upvotes: 1

Thomas Weller
Thomas Weller

Reputation: 59670

It's totally possible with a helper method:

def reverse_recursive(i: int) -> int:
    def helper(i: int, result_up_to_now: int) -> int:
        if i == 0:
            return result_up_to_now
        return helper(i // 10, result_up_to_now * 10 + (i % 10))
    return helper(i, 0)

assert reverse_recursive(123456789) == 987654321

And even without one:

def reverse_recursive_nohelper(i: int, result_up_to_now=0) -> int:
    if i == 0:
        return result_up_to_now
    return reverse_recursive_nohelper(i // 10, result_up_to_now * 10 + (i % 10))

assert reverse_recursive_nohelper(123456789) == 987654321

But the latter one could of course be misused/misunderstood by someone.

Just for comparison, the non-recursive version:

def reverse_straight(i: int) -> int:
    result = 0
    while i != 0:
        result = result*10 + i % 10
        i //= 10
    return result

assert reverse_straight(123456789) == 987654321

Upvotes: 7

Related Questions