Two 6-element lists summed position by position in an index loop. The trace shows i stepping through each index and result accumulating one pairwise sum per iteration.

By hand

Walk each index i from 0 to len(a) - 1. Add a[i] and b[i] and append the sum to result. The same pattern as map-transform in python-data-basics/ch02, but combining two lists rather than transforming one.

naive.py
Replay: real traced execution (multi-file project)
a = [1, 2, 3, 4, 5, 6]
b = [10, 20, 30, 40, 50, 60]
result = []
for i in range(len(a)):
    result.append(a[i] + b[i])
print('RESULT:', result)
  1. a ← [1, 2, 3, 4, 5, 6]

    1a = [1, 2, 3, 4, 5, 6]2b = [10, 20, 30, 40, 50, 60]
    values this step[1, 2, 3, 4, 5, 6]a
  2. b ← [10, 20, 30, 40, 50, 60]

    1a = [1, 2, 3, 4, 5, 6]2b = [10, 20, 30, 40, 50, 60]3result = []
    values this step[10, 20, 30, 40, 50, 60]b
  3. result ← []

    2b = [10, 20, 30, 40, 50, 60]3result = []4for i in range(len(a)):
    values this step[]result
  4. i ← 0

    3result = []4for i in range(len(a)):5    result.append(a[i] + b[i])
    values this step0i
  5. result ← [11]

    4for i in range(len(a)):5    result.append(a[i] + b[i])6print('RESULT:', result)
    values this step[] [11]result
  6. i ← 1

    3result = []4for i in range(len(a)):5    result.append(a[i] + b[i])
    values this step0 1i
  7. result ← [11, 22]

    4for i in range(len(a)):5    result.append(a[i] + b[i])6print('RESULT:', result)
    values this step[11] [11, 22]result
  8. i ← 2

    3result = []4for i in range(len(a)):5    result.append(a[i] + b[i])
    values this step1 2i
  9. result ← [11, 22, 33]

    4for i in range(len(a)):5    result.append(a[i] + b[i])6print('RESULT:', result)
    values this step[11, 22] [11, 22, 33]result
  10. i ← 3

    3result = []4for i in range(len(a)):5    result.append(a[i] + b[i])
    values this step2 3i
  11. result ← [11, 22, 33, 44]

    4for i in range(len(a)):5    result.append(a[i] + b[i])6print('RESULT:', result)
    values this step[11, 22, 33] [11, 22, 33, 44]result
  12. i ← 4

    3result = []4for i in range(len(a)):5    result.append(a[i] + b[i])
    values this step3 4i
  13. result ← [11, 22, 33, 44, 55]

    4for i in range(len(a)):5    result.append(a[i] + b[i])6print('RESULT:', result)
    values this step[11, 22, 33, 44] [11, 22, 33, 44, 55]result
  14. i ← 5

    3result = []4for i in range(len(a)):5    result.append(a[i] + b[i])
    values this step4 5i
  15. result ← [11, 22, 33, 44, 55, 66]

    4for i in range(len(a)):5    result.append(a[i] + b[i])6print('RESULT:', result)
    values this step[11, 22, 33, 44, 55] [11, 22, 33, 44, 55, 66]result
  16. for i in range(len(a)):

    3result = []4for i in range(len(a)):5    result.append(a[i] + b[i])
  17. stdout ← RESULT: [11, 22, 33, 44, 55, 66]

    5    result.append(a[i] + b[i])6print('RESULT:', result)
    values this stepRESULT: [11, 22, 33, 44, 55, 66]stdout

With NumPy

arr_a + arr_b adds the two arrays elementwise without an explicit loop. NumPy iterates in C over the contiguous buffers, applying the addition to every pair of aligned elements at once.

library.py
import numpy as np

a = [1, 2, 3, 4, 5, 6]
b = [10, 20, 30, 40, 50, 60]
arr_a = np.array(a)
arr_b = np.array(b)
result = arr_a + arr_b
print('shape:', result.shape)
print('dtype:', result.dtype)
print('values:', result.tolist())
print('RESULT:', result.tolist())
shape: (6,)
dtype: int64
values: [11, 22, 33, 44, 55, 66]
RESULT: [11, 22, 33, 44, 55, 66]

Implementation notes

  • Both arrays must have compatible shapes for + to work. Two arrays of the same shape always match. Arrays of different shapes may still be compatible via broadcasting — covered in ch06.
  • The + operator calls np.add(arr_a, arr_b) under the hood. NumPy exposes all elementwise operations as both operators and named ufuncs; the ufunc form accepts an optional out= argument to write results into a pre- allocated buffer.
  • Shape, dtype, and values are shown explicitly here because ndarray.__repr__ output varies with NumPy version and print options.