Script to make copies of a shape key, each one with an isolated translate channel I have been reading Jason Osipa's "Stop Staring - Facial Modeling and Animation Done Right". In the book, there is an interesting Mel script I am trying to port to Blender, so far with no success

Basically, the script copies a shape_key andcreates 3 new shape keys, and in each one, the vertices translations in each axis are isolated. Thus we have three new shape keys, one being for the X axis, another being for the Y axis and another for the Z axis. The three combined are equal to the original shape_key.   

I know I can access the coordinates of the vertices in the shape key through:

object.data.shape_keys.key_blocks['Key 1'].data[#].co    


('Key 1' being the shape key name and # the vertex index)

I also know I can access the vertices in their original position through:

bpy.context.object.active_shape_key.data[#].co


(# being the vertex index)

Thus, I thought the code would be something like:

import bpy

context = bpy.context
scene = context.scene
obj = context.object
shape_name = obj.active_shape_key.name

obj.shape_key_add(name=str(shape_name) + "_X", from_mix=True)
obj.shape_key_add(name=str(shape_name) + "_Y", from_mix=True)
obj.shape_key_add(name=str(shape_name) + "_Z", from_mix=True)
bpy.ops.object.shape_key_add(from_mix=False)
bpy.ops.object.shape_key_remove(all=False)   #Hack to select the last shape_key in the list

shape_name = obj.active_shape_key.name #Update the active_shape_key.name

for vert in obj.data.vertices: #Isolate the translation on the Z axis first
    obj.data.shape_keys.key_blocks[shape_name].data[vert.index].co.x = obj.active_shape_key.data[vert.index].co.x
    obj.data.shape_keys.key_blocks[shape_name].data[vert.index].co.y = obj.active_shape_key.data[vert.index].co.y

obj.active_shape_key_index = obj.active_shape_key_index - 2

shape_name = obj.active_shape_key.name

for vert in obj.data.vertices: #Isolate the translation on the X axis
    obj.data.shape_keys.key_blocks[shape_name].data[vert.index].co.y = obj.active_shape_key.data[vert.index].co.y
    obj.data.shape_keys.key_blocks[shape_name].data[vert.index].co.z = obj.active_shape_key.data[vert.index].co.z

obj.active_shape_key_index = obj.active_shape_key_index + 1 

shape_name = obj.active_shape_key.name

for vert in obj.data.vertices: #Isolate the translation on the Y axis
    obj.data.shape_keys.key_blocks[shape_name].data[vert.index].co.x = obj.active_shape_key.data[vert.index].co.x
    obj.data.shape_keys.key_blocks[shape_name].data[vert.index].co.z = obj.active_shape_key.data[vert.index].co.z


However, it does not work and it's driving me mad. Any suggestions?
First point would be that shape_key_add(from_mix=True) will copy the shape key as it is, you may want to be sure that the shapekey is in effect when you copy it.

obj.active_shape_key.value = obj.active_shape_key.slider_max


Rather than changing the active shapekey for each step, get the index of each as you create them and use that when adjusting the copy. The new shapekey will be added to the end of the list so it's index will be len(key_blocks)-1

xshape_idx = len(obj.data.shape_keys.key_blocks)-1


Now the key point -

obj.data.shape_keys.key_blocks[shape_name].data[vert.index].co.x 
  = obj.active_shape_key.data[vert.index].co.x


you set obj.active_shape_key_index then you copy active_shape_key.data[vert.index] into key_blocks[shape_name].data[vert.index] that is two ways to the same data. I would suggest setting the unwanted locations to the Basis shapekey locations.

obj.data.shape_keys.key_blocks[xshape_idx].data[vert.index].co.x 
  = obj.data.shape_keys.key_blocks['Basis'].data[vert.index].co.x


I finished up with -

import bpy

context = bpy.context
scene = context.scene
obj = context.object
shape_name = obj.active_shape_key.name

## enable shapekey before copying
skey_value = obj.active_shape_key.value
obj.active_shape_key.value = obj.active_shape_key.slider_max

obj.shape_key_add(name=str(shape_name) + "_X", from_mix=True)
xshape_idx = len(obj.data.shape_keys.key_blocks)-1
obj.shape_key_add(name=str(shape_name) + "_Y", from_mix=True)
yshape_idx = len(obj.data.shape_keys.key_blocks)-1
obj.shape_key_add(name=str(shape_name) + "_Z", from_mix=True)
zshape_idx = len(obj.data.shape_keys.key_blocks)-1

## reset shapekey
obj.active_shape_key.value = skey_value

for vert in obj.data.vertices: #Isolate the translation on the X axis
    obj.data.shape_keys.key_blocks[xshape_idx].data[vert.index].co.y = obj.data.shape_keys.key_blocks['Basis'].data[vert.index].co.y
    obj.data.shape_keys.key_blocks[xshape_idx].data[vert.index].co.z = obj.data.shape_keys.key_blocks['Basis'].data[vert.index].co.z

for vert in obj.data.vertices: #Isolate the translation on the Y axis
    obj.data.shape_keys.key_blocks[yshape_idx].data[vert.index].co.x = obj.data.shape_keys.key_blocks['Basis'].data[vert.index].co.x
    obj.data.shape_keys.key_blocks[yshape_idx].data[vert.index].co.z = obj.data.shape_keys.key_blocks['Basis'].data[vert.index].co.z

for vert in obj.data.vertices: #Isolate the translation on the Z axis
    obj.data.shape_keys.key_blocks[zshape_idx].data[vert.index].co.x = obj.data.shape_keys.key_blocks['Basis'].data[vert.index].co.x
    obj.data.shape_keys.key_blocks[zshape_idx].data[vert.index].co.y = obj.data.shape_keys.key_blocks['Basis'].data[vert.index].co.y