The OrderedDict will preserve any order that it has access to. The only way to pass ordered data to it to initialize is to pass a list (or, more generally, an iterable) of key-value pairs, as in your last two examples. As the documentation you linked to says, the OrderedDict does not have access to any order when you pass in keyword arguments or a dict argument, since any order there is removed before the OrderedDict constructor sees it.
Note that using a list comprehension in your last example doesn’t change anything. There’s no difference between OrderedDict([(i,i) for i in l])
and OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')])
. The list comprehension is evaluated and creates the list and it is passed in; OrderedDict knows nothing about how it was created.