Finding line numbers of duplicate lines in a log file
To go through your programs:



Load the file into a list - \$O(n)\$ time and memory.
Go through the list and add to a dict - \$O(n)\$ time and memory.
Loop through the new dict: \$O(n)\$ time and memory,
if the item has duplicates, get the lines: \$O(n)\$ time, \$O(1)\$ memory.

In total \$O(n^2)\$ time, \$O(n)\$ memory.


And so it's \$O(n^2)\$ time, \$O(n)\$ memory.

Load the file into a list - \$O(n)\$ time and memory.
Loop through the file - \$O(n)\$ time, \$O(1)\$ memory.
Loop through the file for second index - \$O(n)\$ time and \$O(1)\$ memory.

In total \$O(n^2)\$ time, \$O(n)\$ memory.


It's \$O(n^2)\$ time, and \$O(n)\$ memory.


And so I'd change your program to remove the second loop through the file, to force this you can remove changing the file to a list.
You want to use what you are in (1), but to store a list of all the file indexes. After this you then want to filter all items that don't have a length greater than 1.
And so you should be able to get something like:

from collections import defaultdict

def find_dupl(log):
    output = defaultdict(list)
    with open(log) as f:
        for i, line in enumerate(f):
            output[line].append(i)
    return {k: v for k, v in output.items() if len(v) &gt; 1}


This has \$O(n)\$ time and \$O(n)\$ memory. Yes it does use a module, but it's built in and makes your code much faster, and simpler.