Run one full k-means iteration: assign every point to its nearest centroid, then recompute each centroid as the mean of its cluster. A single loop accumulates per-cluster sums and counts in one pass (no separate assignment list). Library: sklearn KMeans with init=given, n_init=1, max_iter=1. RESULT: updated centroid list [[cx0,cy0],[cx1,cy1]] (rounded).

By hand

With scikit-learn

KMeans(init=given, n_init=1, max_iter=1) performs exactly one assign+update cycle starting from the supplied centroids.

naive.py
points = [[1,2],[2,1],[1,3],[7,6],[8,7],[6,8]]
c0 = [1, 1]
c1 = [7, 7]
sums = [[0.0, 0.0], [0.0, 0.0]]
counts = [0, 0]
for pt in points:
    d0 = (pt[0]-c0[0])**2 + (pt[1]-c0[1])**2
    d1 = (pt[0]-c1[0])**2 + (pt[1]-c1[1])**2
    c = 0 if d0 <= d1 else 1
    sums[c][0] = sums[c][0] + pt[0]
    sums[c][1] = sums[c][1] + pt[1]
    counts[c] = counts[c] + 1
c0 = [round(sums[0][0]/counts[0], 4), round(sums[0][1]/counts[0], 4)]
c1 = [round(sums[1][0]/counts[1], 4), round(sums[1][1]/counts[1], 4)]
print('RESULT:', [c0, c1])
library.py
import numpy as np
from sklearn.cluster import KMeans
from dalib.display import set_display
set_display()

X = np.array([[1,2],[2,1],[1,3],[7,6],[8,7],[6,8]], dtype=float)
init = np.array([[1.0, 1.0], [7.0, 7.0]])
km = KMeans(n_clusters=2, init=init, n_init=1, max_iter=1, random_state=0)
km.fit(X)
print('labels:', km.labels_.tolist())
centroids = [[round(float(v), 4) for v in c] for c in km.cluster_centers_]
print('RESULT:', centroids)
labels: [0, 0, 0, 1, 1, 1]
RESULT: [[1.3333, 2.0], [7.0, 7.0]]

Implementation notes

  • The assign and update steps are fused into a single loop: c = 0 if d0 <= d1 else 1 selects the cluster; sums[c][0] and counts[c] accumulate inline. This avoids storing a separate assignments list while keeping each logical step visible in the replay trace.
  • sklearn's max_iter=1 performs one assign+update cycle and stops — confirmed to match the manual result exactly when init is supplied directly.
  • c1 returns to [7.0,7.0] (unchanged from initialization) because [7,7] is already the exact mean of its three cluster members. A second iteration would produce the same assignments, so the algorithm converges in one step here.
  • Cross-reference: assign-to-centroids and update-centroids (this chapter) for the individual steps shown separately.