4/15 - Any way to do this with lists?


#1

Out of curiosity, is there any way to complete this exercise using lists/for loops?

I.e. Converting the number into a string and adding preceding indexes to the next one


#2

This worked for me, I'm pretty newb still so there is likely a better ('fuller' more complete) way of completing this. Any suggestions would be great :stuck_out_tongue:

def digit_sum(n):
total = 0
n = str(n)
for index in n:
    total += int(index)
return total
print total

#3

Sure is, also using list comprehension is most likely the simplest way.

def digit_sum(data):
    """
    This function converts the data into a string, then iterates over it adding it to
    a list. It then converts it back into an int when it adds it to the list. After that 
    it uses the built-in function sum() to add the list together.
    """
    return sum([int(digit) for digit in str(data)])

#4

Another way of solving this is using recursion:

def digit_sum(n):
    if n == 0:
        return 0
    else:
        return (n % 10) + digit_sum(n // 10)

#5

I like that, - the fact that function calls in python are super expensive.

Though you could also just make it into a one liner using ternary functions.

def digit_sum(number):
    return 0 if number == 0 else (number % 10) + digit_sum(number // 10)

NOTE:
As a note if you do use ternary function in your stuff use them sparsely because after a bit it can make it super difficult to decipher your code.


#6

Well, there is another implementation that leverages tail recursive function and consumes way less memory:

def digit_sum_tail(s, acc):
    return acc if s == 0 else digit_sum_tail(s // 10, acc + (s % 10))

def digit_sum(number):
    return digit_sum_tail(number, 0)

#7

From what I understand tail recursion is not supported in python at all. It's because Guido does not want people to use it. For the reason that it is unpythonic and you can not get good stack trace.

Here is a good post about why you should not rely on it too.

SOURCE: 1 2

Though there is this guy who went ahead and implemented it any ways.


#9

Thanks for useful info, @zeziba. It was actully dumb of me trying to apply tail recursive calls in an imperative language. The last implementation is kind of equivalent to the following:

def digit_sum(number):
    acc = 0
    while number != 0:
        acc += number % 10
        number //= 10
    return acc

#10

If you properly structure your calls and use the right functions/generators python can be just as fast as a c or c++ implementation of the same code. You just have to know the nuisances of python.

Take a look at the stackless python. It is used by Eve online for the whole game, and take care to remember that this game handles thousands of ships at a time firing 10's and 100s of rounds per min per player and does not use a hit chance to calculate if you nail the other guy. It all depends on the programmer just like in any other language.


#11

Can you explain how the else return function works? i dont get in particular what the // does and why did you divide n % 10 or what purpose is digit in the equation. thanks


#12

% is called a modulo operator and it finds the remainder of division of one number by another. So when we apply this operation, we essentially get the rightmost digit of a number, e.g. 123 % 10 returns 3. In order to get the next digit of the number, we should do 12 % 10. You can get 12 by applying integral division of 123 by 10. That's what // operator for. So we eventually get the sum of digits of a number, and for 123 it is 3 + 2 + 1 + 0. Is it clear enough?


#13

This worked for me:

def digit_sum(n):
digits = []
n = str(n)
for x in n:
digits.append(int(x))
return sum(digits)

digit_sum(123)


#14

On 12/15 purify, i tried the modulo thing like the one below

number_list = [1,2,3,4,5,3,6,3,2,1,2,3,4,3]
def purify(x):
_total = []
_for i in x:
__if i % 2 != 1:
___total.append(i)
_return total
print purify(number_list)

the code works as it should. the asnwer being [2, 4, 6, 2, 2, 4]. what i dont get is when lets say 4 % 2 and the answer is that the remainder is 2 and not 1. Why is it still included? sorry, im still very much confused and getting used to all these.


#15

I don't get you either. Since 2 is evenly divisible by 4, how can it be the remainder is 1? I mean 4 % 2 == 0.


#16

oh wait, sorry let me rephrase it. apologies for my confusing question. written in the code is if i % 2 not equal to 1 then it should append it back to total. 2 % 2 is equal to 1 so it appends. why is it when 4 % 2 which is 0 is appended despite not being 1?


#17

How come the remainder of division of 2 by 2 is 1? It's 0! The expression you use (i % 2 != 1) is equivalent to i % 2 == 0, but it's too confusing, whereas the latter is pretty straightforward.


#18

OHH WAIT nevermind!!! found the answer hahaha lol i just switched the != 1 to == 0 lol hahaha thanks. sorry for making heads spin


#19

I have done it in the most easiest way:
def digit_sum(n):
sum=0
for i in range(len(str(n))):
if n>0:
m=n%10
n=n/10
sum += m
return sum


#20

but it seems not to be the right answer ?should it be addition of 1.2.3?


#21

Yes. I created an empty list - digits = []
Stored each integer into the list.
Executed the sum of the list, which would be adding the elements of [1,2,3] together.