Distribute an cylinder to a hexagonal grid with python
This will do the trick (EDITED to also generate ellipses):

import bpy

rowLen = 10 # Number of cylinders per row (along X)
colLen = 10 # Number of cylinders per column (along Y)
xDist  = 4  # Distance between cylinders in X
yDist  = 2  # Distance between cylinders in Y

ellipseRatio = 1.5 # X/Y ratio (cylinder xScale)

for i in range( rowLen ):
    y = i * yDist
    for j in range( colLen ):
        x = j * xDist if i % 2 == 0 else (j + 0.5) * xDist 

        bpy.ops.mesh.primitive_cylinder_add(
            vertices      = 24,
            radius        = 1,
            depth         = 5,
            end_fill_type = 'NGON', 
            location      = (x, y, 0)
        )

        o = bpy.context.object # Newly created cylinder is the active (context) object
        o.scale.x = ellipseRatio


Change the xDist and yDist to control the distance between cylinders in X and Y.
Change the rowLen and colLen to change the number of cylinders in each row or column.

The number of vertices, radius, depth and end fill type are specified within the bpy.ops.mesh.primitive_cylinder_add operator as parameters.