2

I have written a Python function that takes an integer as input and returns the sum of all that number's digits:

def digit_sum(n):
    n_lst = list( str(n) )
    n_sum = 0
    for i in range( len(n_lst) ):
        n_sum += int( n_lst[i] )
    return n_sum

print( digit_sum(1234) )            # 10

Now I wonder if there is a more concise way of doing this perhaps, using a built-in function or list comprehensions?

thefourtheye
  • 233,700
  • 52
  • 457
  • 497

4 Answers4

1

You mean something like this?

sum( [int(x) for x in list(str(n))] )
Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
  • 1
    Converting the string to a list is not necessary, as we can directly iterate the string itself. And, creating a list comprehension is not necessary, as `sum` can work with one value at a time, it doesn't need the entire list to process. – thefourtheye Oct 09 '16 at 10:26
  • 1
    @thefourtheye: Sure; I was trying to show how `sum` and a list comprehension could be used, and figured it would be clearer if the rest was closer to what the OP already understood. – Scott Hunter Oct 09 '16 at 10:30
1

You can convert the number to a string and then add the individual numbers, like this

sum(int(num) for num in str(n))

This uses a generator expression, and sum function iterates the generator expression to keep adding the numbers.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
1

I prefer sum(map(int, str(n))).

TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
  • 1
    Ever since I read http://www.artima.com/weblogs/viewpost.jsp?thread=98196 I am kind of reluctant to use `map`. Apart from that, the code will behave consistently between Py 2 and 3 if I use LC and GE. – thefourtheye Oct 09 '16 at 10:33
  • 1
    @thefourtheye - That guy doesn't know anything about Python! =P Joking aside, `map` is still fine to use (as far as clarity) when you're mapping to a preexisting built-in. It's also slightly faster. And you should use Python 3 exclusively anyway. :) – TigerhawkT3 Oct 09 '16 at 10:37
  • 1
    @TigerhawkT3 I know that nothing wrong in using it, but since the dictator has spoken against it, it kind of feels like a taboo using it :D – thefourtheye Oct 09 '16 at 10:39
0

While all the recent answers are good for "guaranteed" integer input, I'll leave here a sanitized approach(as an alternative) considering "raw" input:

import re

def digit_sum(sequence):
    return sum(int(d) for d in re.findall('\d', sequence))    

print(digit_sum(input("enter some digits"))) 

print(digit_sum("123werwer13!-"))  # 10
print(digit_sum("abbc"))           # 0

re.findall('\d', sequence) - will find all numbers within an input sequence

RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
  • Many thanks. This is genius! (Since I was looking for a one-liner equivalent, I had to mark `sum(map(int, str(n)))` as the correct answer, but your is obviously a brilliant comprehensive solution...) –  Oct 09 '16 at 11:02