Reputation: 133
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)
mysum('spam')
because strings are sequences of one-character strings.mysum(open(name))
, but the others do not because they use index.def mysum(first *rest)
, although similar to the third variant, because it expects individual arguments not a single iterable.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
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
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