Low level modules are "low level" because they have no dependencies, or no relevant dependencies. Very often, they can be easily reused in different contexts without introducing any separate, formal interfaces - which means, reusing them is straightforward, simple and does not require any Dependency Inversion.
High level modules, however, are "high level", because they require other, lower level modules to work. But if they are tied to a specific low-level implementation, they are not easily reusablethis often prevents to reuse them in a different context.
Let us make an example: take a "high-level" module which encapsulates a sorting algorithm. It will usually require two other low-level modules:
an ordered container for the items to be sorted, like a list or array of a certain type
a module which encapsulatedencapsulating a comparison function (a "predicate") for two items
If the sorting module is implemented in a way which directly ties it to a specific typedkind of list, with a specific item type, and a specific form of comparison, it will be hard to reuse in a different context. But if the sorting module is implemented in a more generic fashionBy applying DIP, depending only on an abstract list interfacehowever, and an abstract comparison interfaceone would:
implement the sorting module in a more generic fashion, depending only on an abstract list interface and an abstract comparison interface, and
make the "lower level modules" implement these interfaces.
By this approach, then itthe sorting module can be reused for several kind of lists and all kind of ordering requirements.