Recursion. Slice number to list of digits using recursions

Question:

def slice_num(num, lst=None):
    if lst is None:
        lst = []
    if num > 0:
        lst.append(num % 10)
        slice_num(num//10, lst)
    return lst[::-1]


print(slice_num(564))

Is it the correct way, or was a better choice??

Answers:

If you still insist in using recursion despite the suggestion given from the comments here is a simple approach:

def slice_num(num):
    if num < 0:
        num = -num
    if num == 0:
        return []
    else:
        return slice_num(num // 10) + [num % 10]

print(slice_num(564))

You could even use a one line code if only understand what the above code does:

def slice_num(num):
    return slice_num(num // 10) + [num % 10] if num else []
    
print(slice_num(564))

Both approach will produce the same outpu.
Output:

[5, 6, 4]
Answered By: Jamiu Shaibu

Your attempt seems fine. An alternative that’s a modification of answer Recursion extracting digits that:

  • Avoids needing an extra argument that’s modified
  • Is shorter (single line), so perhaps simpler

Alternative

def slice_num(n):
    return [n] if n < 10 else slice_num(n // 10) + [n % 10]
Answered By: DarrylG

All you need to do is reverse the order of your lst.append and recursive calls, so that the quotient gets turned into a list of digits before adding the remainder to the end of the list. Then you don’t need to reverse the list before returning it.

def slice_num(num, lst=None):
    if lst is None:
        lst = []
    if num > 0:
        slice_num(num//10, lst)
        lst.append(num % 10)

    return lst

There are a number of ways to simplify this.

  1. You can get the quotient and the remainder with a single call:

    def slice_num(num, lst=None):
        if lst is None:
            lst = []
        if num > 0:
            q, r = divmod(num, 10)
            slice_num(q, lst)
            lst.append(r)
        return lst
    
  2. Split this into two functions: a recursive function that modifies lst in place but does not return it, and a wrapper that only takes a number and ensures that the helper is initially called with an empty list.

    def slice_num(num: int) -> [int]:
        lst = []
        _slice_helper(num, lst)
        return lst
    
    def _slice_helper(num: int, lst: list[int]) -> None:
        if num > 0:
            q, r = divmod(num, 10)
            _slice_helper(q, lst)
            lst.append(r)
    

    This follows the Python convention of either modifying a list in place or returning a modified value, not both.

  3. Note that you can use divmod first, and use q == 0 as your base case. This lets you append r to the list unconditionally, as when q == 0 then r == num. It also eliminates a recursive call _slice_helper(0, lst).

    def _slice_helper(num, lst):
        q, r = divmod(num, 10)
        if q > 0:
            _slice_helper(q, lst)
        lst.append(r)
    
Answered By: chepner
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.