Select vertex if vertex color is dark
This will give you a dictionary of colors attached to each vertex:

in the form {vertex_index :  [ color(s) ] ,... } . 

import bpy

mesh = bpy.context.active_object.data
color_layer = mesh.vertex_colors['Col']

tk = {}
i = 0
for poly in mesh.polygons:
    for idx in poly.loop_indices:
        loop = mesh.loops[idx]
        v = loop.vertex_index
        linked = tk.get(v, [])
        linked.append(color_layer.data[i].color)
        tk[v] = linked
        i += 1

print(tk)        


There are nicer ways to write this, using collections.defaultdict. In this example I also import pprint to nicely display the vertex&lt;-->colors dict (tk).

import bpy
from collections import defaultdict

tk = defaultdict(list)

mesh = bpy.context.active_object.data
color_layer = mesh.vertex_colors['Col']

i = 0
for poly in mesh.polygons:
    for idx in poly.loop_indices:
        loop = mesh.loops[idx]
        color = color_layer.data[i].color
        tk[loop.vertex_index].append(color)
        i += 1

# you must cast this as a dict manually like  tk = dict(tk) , 
# if you need it as a dict, but defaultdict will behave mostly the same
import pprint
pprint.pprint(tk)


This will get you as far as being able to average the colors. The output for this Col (for sake of simplicity i use a 9 vertex planar surface)



is

{0: [Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033))],
 1: [Color((0.11372549086809158, 0.800000011920929, 0.0))],
 2: [Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894))],
 3: [Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929))],
 4: [Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033)),
     Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894))],
 5: [Color((0.11372549086809158, 0.800000011920929, 0.0)),
     Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929))],
 6: [Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929)),
     Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894))],
 7: [Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033)),
     Color((0.11372549086809158, 0.800000011920929, 0.0))],
 8: [Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033)),
     Color((0.11372549086809158, 0.800000011920929, 0.0)),
     Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929)),
     Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894))]}


To complete this, here's an example of how to average a list of colors (naturally, for greyscale colors you only have to concentrate on 1 component as R,G and B should all be the same.

import pprint
from mathutils import Color

cols = tk[8]   # unadulterated color list for that vertex
pprint.pprint(cols)

def avg_col(cols):
    avg_col = Color((0.0, 0.0, 0.0))
    for col in cols:
        avg_col += col/len(cols)
    return avg_col

print('average')
col = avg_col(cols)
print(col)


Now using the defaultdict that represents the vertices and their occurrence in vertex_colors you can average them, or do whatever calculations and create a new dict with a dict comprehension.

import pprint
import bpy

vcol_averages = {k: avg_col(v) for k, v in tk.items()}
pprint.pprint(vcol_averages)

''' outputs, nicely the averages.
{0: Color((0.800000011920929, 0.4313725531101227, 0.04313725605607033)),
 1: Color((0.11372549086809158, 0.800000011920929, 0.0)),
 2: Color((0.27450981736183167, 0.27843138575553894, 0.27843138575553894)),
 3: Color((0.7882353067398071, 0.7921568751335144, 0.800000011920929)),
 4: Color((0.5372549295425415, 0.3549019694328308, 0.16078431904315948)),
 5: Color((0.45098039507865906, 0.7960784435272217, 0.4000000059604645)),
 6: Color((0.5313725471496582, 0.5352941155433655, 0.5392156839370728)),
 7: Color((0.45686274766921997, 0.615686297416687, 0.021568628028035164)),
 8: Color((0.4941176474094391, 0.5754902362823486, 0.2803921699523926))}
'''


From this you might create a list of vertex indices following a threshold test.

vertices_of_interest = [k for k, v in vcol_averages.items() if v.r &lt; 0.5]

pprint.pprint(vertices_of_interest)
# [1, 2, 5, 7, 8]


Selecting vertices, is easy once you get to this point.