Parent by loose geometry groups / geometry islands BPY 2.78a

import bpy
import bmesh
from mathutils import Vector

def get_loose_parts(obj):
    me = obj.data
    bm = bmesh.new()
    bm.from_mesh(me)
    bm.verts.ensure_lookup_table()

    islands = []
    visited = set()
    for v in bm.verts:
        if v.index in visited:
            continue
        stack = [v]
        island = set()
        while stack:
            cur = stack.pop()
            if cur.index in visited:
                continue
            visited.add(cur.index)
            island.add(cur.index)
            for e in cur.link_edges:
                other = e.other_vert(cur)
                if other.index not in visited:
                    stack.append(other)
        islands.append(list(island))
    bm.free()
    return islands

def island_centroid(mesh, idxs):
    c = Vector((0,0,0))
    for i in idxs:
        c += mesh.vertices[i].co
    return c / len(idxs)

def assign_one_to_one(mesh_obj, arm_obj, islands):
    mesh = mesh_obj.data
    bones = arm_obj.data.bones

    # ensure vertex groups exist
    for b in bones:
        if b.name not in mesh_obj.vertex_groups:
            mesh_obj.vertex_groups.new(name=b.name)

    # clear all weights
    all_vids = list(range(len(mesh.vertices)))
    for vg in mesh_obj.vertex_groups:
        vg.remove(all_vids)

    # compute world positions
    bone_pos = {
        b.name: arm_obj.matrix_world * b.head_local
        for b in bones
    }
    island_pos = {
        i: mesh_obj.matrix_world * island_centroid(mesh, verts)
        for i, verts in enumerate(islands)
    }

    # build and sort (island, bone, distance)
    pairs = []
    for i, ipos in island_pos.items():
        for bname, bpos in bone_pos.items():
            dist = (ipos - bpos).length
            pairs.append((dist, i, bname))
    pairs.sort(key=lambda x: x[0])

    assigned_islands = set()
    assigned_bones = set()
    matches = {}

    for dist, i, bname in pairs:
        if i in assigned_islands or bname in assigned_bones:
            continue
        matches[i] = bname
        assigned_islands.add(i)
        assigned_bones.add(bname)
        # stop once all islands or all bones are assigned
        if len(assigned_islands) == len(islands) or len(assigned_bones) == len(bones):
            break

    # do the assignments
    for i, bname in matches.items():
        verts = islands[i]
        mesh_obj.vertex_groups[bname].add(verts, 1.0, 'REPLACE')

    print("Assigned %d islands to %d bones." % (len(matches), len(matches)))

def main():
    sel = bpy.context.selected_objects
    if len(sel) != 2:
        print("Select exactly two objects: one mesh, one armature.")
        return
    mesh_obj = next((o for o in sel if o.type=='MESH'), None)
    arm_obj  = next((o for o in sel if o.type=='ARMATURE'), None)
    if not mesh_obj or not arm_obj:
        print("Selection must be one mesh and one armature.")
        return

    islands = get_loose_parts(mesh_obj)
    if not islands:
        print("No loose geometry found.")
        return

    assign_one_to_one(mesh_obj, arm_obj, islands)

main()

Does as the title specified. allows you to select the armature and the mesh and parent by loose geometry groups / geometry islands in blender 2.78a/2.79.