Khi cần tính tổng các chữ số (digit sum) của từng số trong một list, có thể chuyển số thành chuỗi, duyệt từng ký tự và cộng dồn.
Ví dụ
def digit_sum(n):
"""Tính tổng chữ số của một số nguyên (dương hoặc âm)."""
return sum(int(d) for d in str(abs(n)))
my_list = [11, 23, 41, 62, 89, 0, 10, -123, 1005]
print(f"List: {my_list}")
# Tính tổng chữ số cho mỗi phần tử
result = [digit_sum(x) for x in my_list]
print(f"Tổng chữ số: {result}")
# Chi tiết
print("\nChi tiết:")
for num, dsum in zip(my_list, result):
digits = [int(d) for d in str(abs(num))]
print(f" {num:>5} -> {' + '.join(map(str, digits))} = {dsum}")
Kết quả
List: [11, 23, 41, 62, 89, 0, 10, -123, 1005]
Tổng chữ số: [2, 5, 5, 8, 17, 0, 1, 6, 6]
Chi tiết:
11 -> 1 + 1 = 2
23 -> 2 + 3 = 5
41 -> 4 + 1 = 5
62 -> 6 + 2 = 8
89 -> 8 + 9 = 17
0 -> 0 = 0
10 -> 1 + 0 = 1
-123 -> 1 + 2 + 3 = 6
1005 -> 1 + 0 + 0 + 5 = 6
Giải thích
- Hàm
digit_sum()dùngstr(abs(n))chuyển số thành chuỗi (bỏ dấu âm). - Duyệt từng ký tự,
int(d)chuyển về số,sum()cộng dồn. - List comprehension áp dụng cho toàn bộ list.
- Số âm: dùng
abs()để bỏ dấu trừ.
Cách khác: Không dùng string (toán học)
def digit_sum_math(n):
"""Tính tổng chữ số bằng toán học (nhanh hơn cho số lớn)."""
n = abs(n)
total = 0
while n > 0:
total += n % 10
n //= 10
return total
# Test
print(digit_sum_math(12345)) # 15
print(digit_sum_math(0)) # 0
Tổng chữ số lặp cho đến 1 chữ số (Digital Root)
def digital_root(n):
"""Tổng chữ số lặp cho đến 1 chữ số (công thức toán học)."""
if n == 0:
return 0
return 1 + (abs(n) - 1) % 9
print(digital_root(89)) # 8+9=17 -> 1+7=8
print(digital_root(12345)) # 1+2+3+4+5=15 -> 1+5=6
Ứng dụng: Kiểm tra số Armstrong (narcissistic)
def is_armstrong(n):
"""Số Armstrong: tổng lũy thừa chữ số = chính số đó."""
digits = [int(d) for d in str(n)]
k = len(digits)
return sum(d ** k for d in digits) == n
for n in range(1, 10000):
if is_armstrong(n):
print(n, end=' ') # 1 2 3 4 5 6 7 8 9 153 370 371 407
Hiệu năng: So sánh các cách
import timeit
setup = "n = 123456789"
print("String:", timeit.timeit("sum(int(d) for d in str(n))", setup, number=10000))
print("Math :", timeit.timeit("""
total = 0
while n > 0:
total += n % 10
n //= 10
""", setup, number=10000))
# Math thường nhanh hơn ~2-3x