What (list_get ) does is it returns the information in an object list from a specific slot, or index. (players) is a global object list that updates when players join or leave a game, multiplayer or singleplayer, and is used to reference any player character currently in the game.
As an example, if I wanted to scale player 3 pretty small, I would run
(object_set_scale <object> 0.25 1)
while referencing that player 3 as the object.
(list_get ) is used to return an object from the global list of players:
(list_get (players) <index>)
And we use an index of
2, because (players) list is 0 indexed, or is as diagrammed below:

Final product:
(object_set_scale (list_get (players) 2) 0.25 1)
How do we know if player 3 is the one we wanted to shrink? We don't. Someone could leave, die, etc. and we'd have a new player occupying index number 2, or the one we wanted all along have been in index 5. It's up to the script writer to create a method for determining who is who during runtime.
Now... as far as returning a unit type... this is only necessary when a command requires a unit. Things like (unit_get_health <unit>), (custom_animation <unit> <animation_graph> <string> <boolean>), (vehicle_load_magic <unit> <string> <object_list>), etc. require a unit, whereas commands such as (object_beautify <object> <boolean>), (object_set_collideable <object> <boolean>), and even (effect_new_on_object_marker <effect> <object> <string>) only require an object.
It doesn't cause any problems to have a unit used in place of an object, but in order for objects to be used as a unit, then they need to be converted. Because (players) is an object_list, and (list_get ) returns objects, it is usually more convenient to everything to a unit at the time of it being called. This is why we always see (unit (list_get (players)
0)).
Hope this was at all helpful, and that I didn't completely miss the problem.