Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Python - Tổng chữ số của các số trong List

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ùng str(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