sum() Function Complexity¶
The sum() function returns the sum of all items in an iterable, optionally adding a start value.
Complexity Analysis¶
| Case | Time | Space | Notes |
|---|---|---|---|
| Summing integers | O(n) | O(1) | Single pass, accumulation |
| Summing floats | O(n) | O(1) | Same as integers |
| Summing strings (concatenation) | O(n²) | O(n) | Avoid! Each concatenation copies; use ''.join() |
| With custom objects | O(n*k) | O(1) | k = add time |
Basic Usage¶
Summing Numbers¶
# O(n) - single pass through items
numbers = [1, 2, 3, 4, 5]
total = sum(numbers) # 15
# Works with any numeric iterable
total = sum([1.5, 2.5, 3.0]) # 7.0
total = sum(range(100)) # 4950
total = sum((10, 20, 30)) # 60
# With start value
total = sum([1, 2, 3], start=100) # 106
Generator Expressions¶
# O(n) - evaluates generator once
total = sum(x for x in range(10)) # 45
total = sum(x**2 for x in range(5)) # 30
# More efficient than creating list first
total = sum(x for x in range(1000000)) # O(n) time, O(1) space
# vs creating list first
total = sum([x for x in range(1000000)]) # O(n) time, O(n) space
Common Patterns¶
Counting Items¶
# O(n) - count 1s
count = sum([1 for x in range(100) if x % 2 == 0]) # 50 even numbers
# Better: use len() or sum with boolean
count = sum(1 for x in range(100) if x % 2 == 0) # Still O(n)
Computing Statistics¶
# O(n) - single pass
numbers = [1, 2, 3, 4, 5]
total = sum(numbers)
average = total / len(numbers)
# Don't do this - O(2n)
average = sum(numbers) / len(numbers) # Iterate twice
Flattening Lists¶
# O(n²) - inefficient!
# Each sum call is O(n), and we have n lists
nested = [[1, 2], [3, 4], [5, 6]]
flat = sum(nested, []) # O(n²) - avoid this!
# Better approaches:
# O(n) - single iteration
from itertools import chain
flat = list(chain(*nested))
# O(n) - unpacking
flat = [item for sublist in nested for item in sublist]
Performance Considerations¶
Integer vs Float Arithmetic¶
# Both O(n) but integers are slightly faster
sum([1, 2, 3, 4, 5]) # O(n) - integers
sum([1.0, 2.0, 3.0, 4.0, 5.0]) # O(n) - floats (slightly slower)
Why Not for Strings¶
# ❌ O(n²) - avoid!
# Each + creates new string and copies all data
text = ""
for word in ["a", "b", "c", "d", "e"]:
text = text + word # Creates new string each time
# ❌ Still O(n²) - sum with strings is also quadratic!
# text = sum(["a", "b", "c", "d", "e"], "") # Don't use
# ✅ Best: O(n) with join
text = "".join(["a", "b", "c", "d", "e"])
Working with Custom Objects¶
Custom add Method¶
# O(n*k) where k = time for __add__
class Vector:
def __init__(self, *components):
self.components = components
def __add__(self, other):
# O(m) where m = number of components
return Vector(*(a + b for a, b in zip(self.components, other.components)))
def __repr__(self):
return f"Vector{self.components}"
vectors = [Vector(1, 2), Vector(3, 4), Vector(5, 6)]
result = sum(vectors, Vector(0, 0)) # Vector(9, 12)
# Complexity: O(n*m) where n=3 vectors, m=2 components
Default Start Value¶
# Important: start value type must support __add__
result = sum([1, 2, 3], start=0) # 6
result = sum([1, 2, 3], start=10) # 16
# Start value is crucial for types
result = sum(["a", "b", "c"], start="") # "abc" - O(n²)
result = sum(["a", "b", "c"]) # TypeError - can't add str + int
Comparison with Alternatives¶
vs Loop¶
# sum() - O(n), clean, optimized
numbers = list(range(10000))
total = sum(numbers)
# Manual loop - O(n), same but more verbose
total = 0
for num in numbers:
total += num
# Both have same complexity, sum() is preferred
vs Accumulate¶
from itertools import accumulate
# sum() - O(n), returns single value
numbers = [1, 2, 3, 4, 5]
total = sum(numbers) # 15
# accumulate - O(n) but returns all intermediate sums
totals = list(accumulate(numbers)) # [1, 3, 6, 10, 15]
Pitfalls¶
Floating Point Precision¶
# Summing floats can lose precision
numbers = [0.1] * 10
print(sum(numbers)) # 1.0000000000000007, not exactly 1.0
# Better: use decimal for financial calculations
from decimal import Decimal
numbers = [Decimal('0.1')] * 10
print(sum(numbers, Decimal('0'))) # Exact: 1.0
Empty Sequence¶
# sum() of empty is 0
result = sum([]) # 0
# Or start value
result = sum([], start=100) # 100
# But TypeError with strings if no start
try:
sum(["a", "b"]) # TypeError
except TypeError:
pass
# Works with start=""
result = sum(["a", "b"], start="") # "ab"
Performance Notes¶
# Timing comparison: sum vs alternatives
# O(n) - optimal for summing numbers
sum(range(1000000))
# O(n) but requires list creation first
__builtins__.sum(list(range(1000000)))
# O(n*log(n)) - much slower
sorted([1,2,3])[0] + sorted([1,2,3])[1] # Don't do this
# O(n) - alternative using math.fsum for precision
from math import fsum
fsum([0.1] * 10) # More precise for floats
Best Practices¶
✅ Do:
- Use
sum()for numeric aggregation - Use generator expressions with
sum()for memory efficiency - Use
sum([], start=[])with explicit start value - Use
math.fsum()when precision matters
❌ Avoid:
sum(nested_lists, [])- O(n²) concatenationsum(strings, "")- inefficient string concatenation- Forgetting start value (causes TypeError with non-numeric sequences)
- Summing booleans when
any()orall()is clearer
Related Functions¶
- any() - Check if any item is true
- all() - Check if all items are true
- max() - Find maximum value
- min() - Find minimum value
- math.fsum() - Precise float summation
Version Notes¶
- Python 2.x: Basic functionality available
- Python 3.x: Same behavior, more consistent
- Python 3.8+: No changes to complexity