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.  
![material link button][1]

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


  [1]: https://i.sstatic.net/Zh5w5.png