creating two groups of joined objects using python
Beware the naming system

There is an issue with this part of your code, I've added a print statement boolean  if the object you have chosen as currentSphere is also the newly created sphere.  bpy.data.objects["sphere0"] will always be the first object created with this name. Running again with any objects with the same name existing, will give somewhat unpredictable results.

for coord in coords:
    bpy.ops.mesh.primitive_uv_sphere_add(location=(coord[0],coord[1],coord[2]), size=0.5)
    name = 'sphere' + str(count)
    bpy.context.active_object.name = name

    currentSphere = bpy.data.objects[name]
    print(currentSphere is bpy.context.active_object)


could use something like below, where the currentSphere will be the newly created object, but may not end up with the name you choose. (To make sure it has unique name would need to check and rename/remove others)

for coord in coords:
    bpy.ops.mesh.primitive_uv_sphere_add(location=(coord[0],coord[1],coord[2]), size=0.5)
    name = 'sphere' + str(count)
    currentSphere = bpy.context.active_object
    currentSphere.name = name
    currentSphere.data.materials.append(materialColors[count%2])
    spheres[count%2].append(currentSphere)
    count += 1


I also contend in this case can set context, rather than overriding.

for i in range(2):
    for o in scene.objects:
        o.select = o in spheres[i]   
    scene.objects.active = spheres[i][0]
    bpy.ops.object.join()


Bmesh approach

Another suggestion would be scrapping the primitive add and join operators altogether and use bmesh to create spheres at coordinates.  Test script, creates two bmeshes for odd and even coordinates, and writes the first to active object's mesh.

import bpy
import bmesh
from mathutils import Matrix

coords = [(0, 0, 1), (1, 0, 0), (0, 1, 0), (1, 1, 0)]
bmeshes = [bmesh.new(), bmesh.new()]
for i, coord in enumerate(coords):
    bmesh.ops.create_uvsphere(bmeshes[i % 2],
        u_segments = 16,
        v_segments = 8,
        matrix=Matrix.Translation(coord), 
        diameter=0.5)

# for example sake to mesh onto active_ob
me = bpy.context.object.data
bmeshes[0].to_mesh(me)
me.update()
for bm in bmeshes:
    bm.free()