0

I am asked to define a function that takes in a list and returns another list, all that while using recursion. However when I run the else command and I print the lst_ , the output shows that on every run the list contains a single element, instead of having the doubles added one by one.Also I try not to use append() Thoughts?

def double(lst, lst_ = []):
    """
    parameters : lst of type list;
    returns : another list with lst's elements doubled
    """
    if len(lst) == 0:
        return lst_
    else:
        lst[0] = int(lst[0]) + int(lst[0])
        lst_ = lst_ + lst[0:1]            
        print(lst_)
        return double(lst[1:])

print(double([1,2,3,4,5,6,7,8]))

This is the output

[2]
[4]
[6]
[8]
[10]
[12]
[14]
[16]
[]

4 Answers4

1

If the idea is to return a copy without modifying the original, I would not recommend using the mutable default argument.

Instead,

def double(lst):
    if not lst:
        return []
    return [2*lst[0], *double(lst[1:])] # [2*lst[0]] + double(lst[1:]) 

The recursive case must return a fresh list, and the base case will check for, and return an empty list.

lst1 = double([1,2,3,4,5,6,7,8]) 
print(lst1)
[2, 4, 6, 8, 10, 12, 14, 16]

If you want to have a little fun, you can attempt a generator-based recursive solution using yield from (generator delegation):

def double(lst):
    if lst:
        yield 2*lst[0]
        yield from double(lst[1:])

lst = list(double([1,2,3,4,5,6,7,8]) )
print(lst)
[2, 4, 6, 8, 10, 12, 14, 16]
cs95
  • 379,657
  • 97
  • 704
  • 746
0

Try this way:

def double(lst, lst_ = []):
  if len(lst) == 0:
    return lst_
  else:
    lst[0] = int(lst[0]) + int(lst[0])
    lst_.extend(lst[:1])
    return double(lst[1:])

print(double([1,2,3,4,5,6,7,8]))

#=> [2, 4, 6, 8, 10, 12, 14, 16]
iGian
  • 11,023
  • 3
  • 21
  • 36
0

Use .append() on list to add elements at the end:

def double(lst, lst_ = []):
    """
    parameters : lst of type list;
    returns : another list with lst's elements doubled
    """
    if len(lst) == 0:
        return lst_
    else:
        lst[0] += lst[0]
        lst_.append(lst[0])          
        return double(lst[1:])

print(double([1,2,3,4,5,6,7,8]))
# [2, 4, 6, 8, 10, 12, 14, 16]

Also, note that this line lst[0] = int(lst[0]) + int(lst[0]) in you code can be shortened to lst[0] += lst[0], because you are dealing with integers only and that explicit casting is redundant.

Austin
  • 25,759
  • 4
  • 25
  • 48
0

If you don't want to use append(). Then you can use this solution:

def double(lst, lst_ = []):
    if not lst:
        return lst_
    else:
        return [lst[0] * 2 , *double(lst[1:])]

print(double([1,2,3,4,5,6,7,8]))

The output will be : [2, 4, 6, 8, 10, 12, 14, 16]

Just in case you are wondering with the *double(lst[1:]) call: *[] is used for unpacking argument list. Read more here. If you call without the * you will get an output like:

[2, [4, [6, [8, [10, [12, [14, [16, []]]]]]]]]

Another easy solution will be:

def double(lst, lst_ = []):
    if not lst:
        return lst_
    else:
        lst[0] = lst[0] * 2
        lst_ = lst_.append(lst[0])
        return double(lst[1:])

print(double([1,2,3,4,5,6,7,8]))
Anurag
  • 482
  • 6
  • 23