Summiere die Ziffern einer Zahl


78

Wenn ich die Summe der Ziffern einer Zahl finden möchte, dh:

  • Eingang: 932
  • Ausgabe : 14, was ist(9 + 3 + 2)

Was ist der schnellste Weg, dies zu tun?

Ich tat instinktiv:

sum(int(digit) for digit in str(number))

und ich fand das online:

sum(map(int, str(number)))

Welches ist am besten für die Geschwindigkeit geeignet, und gibt es andere Methoden, die noch schneller sind?


3
Diese sind gut und gleichwertig. mapist etwas schneller.
Pavel Anossov

Sie können x % 9diesen Artikel lesen
Washington Guedes

Antworten:


113

Beide Zeilen, die Sie gepostet haben, sind in Ordnung, aber Sie können es nur in ganzen Zahlen tun, und es wird am effizientesten sein:

def sum_digits(n):
    s = 0
    while n:
        s += n % 10
        n //= 10
    return s

oder mit divmod:

def sum_digits2(n):
    s = 0
    while n:
        n, remainder = divmod(n, 10)
        s += remainder
    return s

Noch schneller ist die Version ohne erweiterte Zuweisungen:

def sum_digits3(n):
   r = 0
   while n:
       r, n = r + n % 10, n // 10
   return r

> %timeit sum_digits(n)
1000000 loops, best of 3: 574 ns per loop

> %timeit sum_digits2(n)
1000000 loops, best of 3: 716 ns per loop

> %timeit sum_digits3(n)
1000000 loops, best of 3: 479 ns per loop

> %timeit sum(map(int, str(n)))
1000000 loops, best of 3: 1.42 us per loop

> %timeit sum([int(digit) for digit in str(n)])
100000 loops, best of 3: 1.52 us per loop

> %timeit sum(int(digit) for digit in str(n))
100000 loops, best of 3: 2.04 us per loop

3
sum_digits3 () sollte wahrscheinlich //anstelle von verwenden /, oder? Ansonsten bekomme ich falsche Antworten.
LarsH

Darf ich hier eine Erklärung zu "while n:" benötigen? Ich weiß nicht, wie Python versteht, wann ich aufhören soll. Zum Beispiel sollte die Summe der Ziffern von 324 3 + 2 + 4 sein. Für die letzte (die vordere Ziffer drei) in der while-Schleife ist 3/10 = 0 und dann wird es "while 0:". Bedeutet also 0 Falsch für die Schleife und entkommt dann der Schleife und gibt s zurück?
Nam

3
Ja, einige Dinge entsprechen False an Stellen, an denen boolesche Werte erwartet werden. Siehe hier: docs.python.org/2/library/stdtypes.html#truth-value-testing
Pavel Anossov

1
Gibt es eine Möglichkeit, die Summe der Ziffern einer ungeraden Folge von ganzen Zahlen durch eine Formel zu finden?
Anoop Toffy

5
Was ist der Wert nIhrer% timeit-Anrufe?
d8aninja

15

Wenn Sie die Ziffern so lange summieren möchten, bis Sie eine einstellige Zahl erhalten (eines meiner Lieblingsmerkmale von durch 9 teilbaren Zahlen), können Sie Folgendes tun:

def digital_root(n):
    x = sum(int(digit) for digit in str(n))
    if x < 10:
        return x
    else:
        return digital_root(x)

Was sich selbst als ziemlich schnell herausstellt ...

%timeit digital_root(12312658419614961365)

10000 loops, best of 3: 22.6 µs per loop

1
Clever, die Funktion in sich zusammenfalten!
Vashts85

Rekursion! @ vashts85
d8aninja

Ich auch, was ist es mit teilbar durch 9?
Ronaldo Nascimento

@ RonaldoNascimento Ich weiß nicht, aber es fasziniert mich. Und 3s.
d8aninja

1
Für die digitale Wurzel (von Basis 10 Zahlen) gibt es eine direkte Formel:digital_root(n) = n-9*(n-1//9)
Reschu

7

Dies könnte helfen

def digit_sum(n):
    num_str = str(n)
    sum = 0
    for i in range(0, len(num_str)):
        sum += int(num_str[i])
    return sum

1
danke, dieser hat mir bei dem problem geholfen: prüfe ob die angegebene nummer modulo 0 geben kann, nachdem du ihre ziffern zusammengefasst hast.
Yannis Dran

4

Bei einigen Codecademy-Herausforderungen habe ich Folgendes gelöst:

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

2

Fand dies auf einer der Websites zur Problemlösung. Nicht meins, aber es funktioniert.

num = 0            # replace 0 with whatever number you want to sum up
print(sum([int(k) for k in str(num)]))

1

Hier ist eine Lösung ohne Schleife oder Rekursion, die jedoch nur für nicht negative Ganzzahlen funktioniert (Python3):

def sum_digits(n):
    if n > 0:
        s = (n-1) // 9    
        return n-9*s
    return 0

1

Der beste Weg ist, Mathe zu verwenden.
Ich wusste das aus der Schule (irgendwie auch aus Codewars)

def digital_sum(num):
    return (num % 9) or num and 9

Ich weiß nur nicht, wie das im Code funktioniert, aber ich weiß, dass es Mathe ist

Wenn eine Zahl durch 9 teilbar ist, ist digital_sum 9,
wenn dies nicht der Fall ist num % 9, ist die digitale Summe.


Eine Erklärung finden Sie unter dem Link in diesem Kommentar .
Snakecharmerb

0
def digitsum(n):
    result = 0
    for i in range(len(str(n))):
        result = result + int(str(n)[i:i+1])
    return(result)

"Ergebnis" wird mit 0 initialisiert.

Innerhalb der for-Schleife wird die Zahl (n) in eine Zeichenfolge umgewandelt, die mit dem Schleifenindex (i) geteilt wird und jede Ziffer erhält. ---> str (n) [ i: i + 1 ]

Diese in Scheiben geschnittene Ziffer wird zurück in eine ganze Zahl konvertiert ----> int (str (n) [i: i + 1])

Und damit zum Ergebnis hinzugefügt.


2
Bitte fügen Sie ein paar Wörter hinzu, um Ihren Code zu erklären und wie er die Frage beantwortet.
Yannis

0
def sumOfDigits():

    n=int(input("enter digit:")) 
    sum=0
    while n!=0 :

        m=n%10
        n=n/10
        sum=int(sum+m)

    print(sum)

sumOfDigits()

5
Hallo! Willkommen auf der Seite! Ihre Antwort scheint zwar eine gültige Lösung für das Problem zu sein, beantwortet jedoch nicht die Frage selbst: "Was ist schneller?" Können Sie angesichts der Frage der Geschwindigkeit die Testergebnisse Ihrer Lösung im Vergleich zu den angegebenen Beispielen anzeigen?
Freundlicher Fremder

0

Sie können dies auch mit der integrierten Funktion divmod () versuchen.

number = int(input('enter any integer: = '))
sum = 0
while number!=0: 
    take = divmod(number, 10) 
    dig = take[1] 
    sum += dig 
    number = take[0] 
print(sum) 

Sie können eine beliebige Anzahl von Ziffern nehmen


0
reduce(op.add,map(int,list(str(number))))

Prüfung:

from datetime import datetime
number=49263985629356279356927356923569976549123548126856926293658923658923658923658972365297865987236523786598236592386592386589236592365293865923876592385623987659238756239875692387659238756239875692856239856238563286598237592875498259826592356923659283756982375692835692385653418923564912354687123548712354827354827354823548723548235482735482354827354823548235482354823548235482735482735482735482354823548235489235648293548235492185348235481235482354823548235482354823548235482354823548234



startTime = datetime.now()

for _ in  range(0,100000) :
    out=reduce(op.add,map(int,list(str(number))))

now=datetime.now()
runningTime=(now - startTime)

print ("Running time:%s" % runningTime)
print(out)

Laufzeit: 0: 00: 13.122560 2462



0

Ich habe eine rekursive Lösung gefunden:

def sumDigits(num):
#   print "evaluating:", num
  if num < 10:
    return num

  # solution 1
#   res = num/10
#   rem = num%10
#   print "res:", res, "rem:", rem
#   return sumDigits(res+rem)

    # solution 2
  arr = [int(i) for i in str(num)]
  return sumDigits(sum(arr))

# print(sumDigits(1))
# print(sumDigits(49))
print(sumDigits(439230))
# print(sumDigits(439237))

0

Eine Basis-10-Zahl kann als eine Reihe der Form ausgedrückt werden

a × 10 ^ p + b × 10 ^ p-1 .. z × 10 ^ 0

Die Summe der Ziffern einer Zahl ist also die Summe der Koeffizienten der Terme.

Basierend auf diesen Informationen kann die Summe der Ziffern wie folgt berechnet werden:

import math

def add_digits(n):
    # Assume n >= 0, else we should take abs(n)
    if 0 <= n < 10:
        return n
    r = 0
    ndigits = int(math.log10(n))
    for p in range(ndigits, -1, -1):
        d, n = divmod(n, 10 ** p)
        r += d
    return r

Dies ist effektiv die Umkehrung der kontinuierlichen Division durch 10 in der akzeptierten Antwort. Angesichts der zusätzlichen Berechnung dieser Funktion im Vergleich zur akzeptierten Antwort ist es nicht überraschend, dass dieser Ansatz im Vergleich schlecht abschneidet: Er ist ungefähr 3,5-mal langsamer und ungefähr doppelt so langsam wie

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

-1
num = 123
dig = 0
sum = 0
while(num > 0):
  dig = int(num%10)
  sum = sum+dig
  num = num/10

print (sum) // Stellen Sie sicher, dass über dieser Zeile Leerzeichen eingefügt werden


numist nicht kleiner als 0. Nichts wird passieren. Machen Sie das größer als und das kann funktionieren.
Sorak

Ja ... aus Versehen war es weniger als. jetzt ist es größer als und funktioniert gut
Jayant Pandey

-1

Sie können dies versuchen

def sumDigits(number):
    sum = 0
    while(number>0):
        lastdigit = number%10
        sum += lastdigit
        number = number//10

    return sum

-2

Es funktioniert nur für dreistellige Zahlen, aber es funktioniert

a = int(input())
print(a // 100 + a // 10 % 10 + a % 10)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.