Dan
Dan

Reputation: 133

Clarification on what the author meant (Learning Python 5th Edition)

def mysum(L):
    return 0 if not L else L[0] + mysum(L[1:])

def mysum(L):
   return L[0] if len(L) == 1 else L[0] + mysum(L[1:])

def mysum(L):
    first, *rest = L
    return first if not rest else first + mysum(rest)

The author seems to be implying that the variant with (first, *rest) as the input arguments wouldn't work with files but after experimenting with it, I found that it does work.

# Code I tried:
def mysum(first, *rest): 
    return first if not rest else first + mysum(*rest)

mysum(*open("script1.py")) works fine.

I think mysum(open("script1.py")) won't work because that what python would then see is first = open("script1.py and rest = [] which means it's gonna give me the <_io.TextIOWrapper name='script1.py' mode='r' encoding='cp1252'> because not [] is true.

Upvotes: 1

Views: 76

Answers (2)

Charitoo
Charitoo

Reputation: 1872

Using a tuple to explain what happens. The *sequence syntax is used for unpacking.

numbers = (1, 2, 3)

mysum(*numbers)   # this happens: mysum(1, 2, 3)

is equivalent to mysum(1, 2, 3). The members are taken from the iterable and fed into the function as arguments. Using *open('path/to/file') causes the file to be opened and its contents passed into mysum(L) as arguments. This is equivalent to mysum(open('path/to/file').read())

Upvotes: 1

Jonas Adler
Jonas Adler

Reputation: 10759

The author wants a function that takes an iterable (e.g. a list, tuple, etc) as input and returns the sum, e.g. like this:

mysum(open("script1.py"))

When you write

mysum(*open("script1.py"))

This is roughly equivalent to

f = open("script1.py").readlines()
mysum(f[0], f[1], ..., f[n])

Note that here your code does not take an interable as input, instead it takes several separate arguments which is not what the author wanted.

Upvotes: 2

Related Questions