I haven’t looked closely at the Blender code regarding selection, but in my experience the Blender Python API is just a thin layer on top of the underlying C or C++ code. So when it comes to (say) the set of selected vertices there probably is no explicit object representing that, as I suspect each vertex has an associated flag, just like there’s a select
attribute in Python. Meaning: selection is represented implicitly by the per-vertex flag, which is why looping through the set of vertices to get the selection is the way to go. But then again, I might be wrong 
Now, there could be an extra operation in the Python API to make it easier to extract that selection, even when in edit-mode, but there isn’t one apparently. I guess this is an example case of how open-source is different from commercial software. If someone wants a certain feature badly enough and is capable of writing it themselves then such a software patch might get submitted to the Blender source repositories and end up in Blender. I recently had a minor feature I was missing (background rectangles on text items in the video sequencer) get accepted in this way. There simply isn’t a marketing/sales department for Blender that is actively monitoring customer satistifaction, driving the roadmap, etc. The contacts the Blender institute and devs have with the larger studios obviously have influence in this respect, but it’s not the same.
Anyways, more concretely, when in edit-mode you can use a BMesh object and loop through that to get the selection, e.g. in the Python console:
# Having a mesh in edit-mode, with some vertices selected
>>> import bmesh
>>> o = bpy.context.active_object
>>> m = o.data
# Create a BMesh object, mesh m needs to be in edit-mode
>>> bm = bmesh.from_edit_mesh(m)
# Retrieve the selection
>>> [v for v in bm.verts if v.select]
[<BMVert(0x7f6260aae590), index=0>, <BMVert(0x7f6260aae5c8), index=1>]
# After changing the vertex selection on the mesh (still in edit-mode!)
>>> [v for v in bm.verts if v.select]
[<BMVert(0x7f6260aae600), index=2>, <BMVert(0x7f6260aae638), index=3>, <BMVert(0x7f6260aae670), index=4>, <BMVert(0x7f6260aae6e0), index=6>]
# When done clean up the BMesh object
>>> bm.free()
>>> bm
<BMesh dead at 0x7f6262c16f00>
To match up the indices shown with the mesh you would need to enable Developer extras under Preferences > Interface > Display, and then in the Viewport overlay settings (the intersecting balls in the top-right) enable Indices under Developer. Yes, very convoluted. But it probably also reflects that this isn’t a widely used feature (or people just give up trying to get it to work). There might also be better ways to do this that I’m not aware off. Perhaps there’s an addon that makes this easier, although a quick google search just now didn’t turn up one.
Edit: just noticed this overlaps quite a bit with the answers from @Debuk, but perhaps gives you a few more concrete things to use