Because you are copying one object, all the object data is the same. Because of that you can not add different materials to the object data (there is only one). Instead you will need to assign the material to the object, not the objects data.
These five lines below are what create a material, add it to the object and set the link to object, instead of the default object data. The diffuse_color = [R, G, B]
is where you specify the color you would like that material to have (blender is expecting value between 0.0 and 1.0 for each color channel). Keep in mine this code is only for cycles, the blender internal render has a different way of doing materials.
mat = bpy.data.materials.new("materialName")
mat.diffuse_color = [R, G, B]
ob.active_material = mat
ob.material_slots[0].link = 'OBJECT'
ob.material_slots[0].material = mat
Full edited code below.
import bpy
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.mesh.primitive_uv_sphere_add()
sphere = bpy.context.object
R,G,B = 1,0,0
for i in range(-1000, 1000, 2):
ob = sphere.copy()
ob.location.y = i
bpy.context.scene.objects.link(ob)
mat = bpy.data.materials.new("materialName")
mat.diffuse_color = [R, G, B]
ob.active_material = mat
ob.material_slots[0].link = 'OBJECT'
ob.material_slots[0].material = mat
bpy.context.scene.update() # version < 2.8
# bpy.context.view_layer.update() # version 2.8