push the data through pipeline of coroutines even just basic for loop the generator version seems to be most readableso let' add that function to our programfrom random import random def generate_colors(count= )for in range(count)yield (random()random()random()notice how we parameterize the number of colors to generate we can now reuse this function for other color-generating tasks in the future nowbefore we do the classification stepwe need function to calculate the "distancebetween two colors since it' possible to think of colors as being three dimensional (redgreenand blue could map to xyand axesfor example)let' use little basic mathimport math def color_distance(color color )channels zip(color color sum_distance_squared for in channelssum_distance_squared +( * return math sqrt(sum_distance_squaredthis is pretty basic-looking functionit doesn' look like it' even using the iterator protocol there' no yield functionno comprehensions howeverthere is for loopand that call to the zip function is doing some real iteration as well (remember that zip yields tuples containing one element from each input iteratornotehoweverthat this function is going to be called lot of times inside our -nearest neighbors algorithm if our code ran too slow and we were able to identify this function as bottleneckwe might want to replace it with less readablebut more optimizedgenerator expressiondef color_distance(color color )return math sqrt(sum(( [ [ ]* for in zipcolor color ))