Python losowe N linii z dużego pliku (bez duplikatów linii)

Muszę użyć pythona do pobrania N liczby linii z dużego pliku txt. Te pliki są w zasadzie tabelami rozdzielanymi tabulatorami. Moje zadanie ma następujące ograniczenia:

Pliki te mogą zawierać nagłówki (niektóre mają nagłówki wieloliniowe).Nagłówki muszą pojawiać się na wyjściu w tej samej kolejności.Każda linia może być wykonana tylko raz.Największy plik ma obecnie około 150 GB (około 60 000 000 linii).Linie są mniej więcej tej samej długości w pliku, ale mogą się różnić między różnymi plikami.Zwykle biorę 5000 losowych linii (mogę potrzebować do 1 000 000 linii)

Obecnie napisałem następujący kod:

inputSize=os.path.getsize(options.input)
usedPositions=[] #Start positions of the lines already in output

with open(options.input) as input:
    with open(options.output, 'w') as output:

        #Handling of header lines
        for i in range(int(options.header)):
            output.write(input.readline())
            usedPositions.append(input.tell())

        # Find and write all random lines, except last
        for j in range(int(args[0])):
            input.seek(random.randrange(inputSize)) # Seek to random position in file (probably middle of line)
            input.readline() # Read the line (probably incomplete). Next input.readline() results in a complete line.
            while input.tell() in usedPositions: # Take a new line if current one is taken
                input.seek(random.randrange(inputSize))
                input.readline() 
            usedPositions.append(input.tell()) # Add line start position to usedPositions
            randomLine=input.readline() # Complete line
            if len(randomLine) == 0: # Take first line if end of the file is reached
                input.seek(0)
                for i in range(int(options.header)): # Exclude headers
                    input.readline()
                randomLine=input.readline()
            output.write(randomLine)            

Ten kod wydaje się działać poprawnie.

Wiem, że ten kod preferuje linie, które podążają za najdłuższymi liniami na wejściu, ponieważ seek () najprawdopodobniej zwróci pozycję na najdłuższej linii, a następny wiersz zostanie zapisany na wyjściu. Nie ma to znaczenia, ponieważ linie w pliku wejściowym są mniej więcej tej samej długości. Wiem też, że ten kod powoduje nieskończoną pętlę, jeśli N jest większe niż liczba linii w pliku wejściowym. Nie zaimplementuję tego sprawdzenia, ponieważ uzyskanie liczby linii zajmuje dużo czasu.

Ograniczenia pamięci RAM i HDD są nieistotne. Martwię się tylko szybkością programu. Czy istnieje sposób na dalszą optymalizację tego kodu? A może jest lepsze podejście?

EDYTOWAĆ: Aby wyjaśnić, linie w jednym pliku mają mniej więcej tę samą długość. Mam jednak wiele plików, które ten skrypt musi uruchomić, a średnia długość linii będzie inna dla tych plików. Na przykład plik A może mieć ~ 100 znaków na linię i plik B ~ 50000 znaków w linii. Nie znam wcześniej średniej długości linii żadnego pliku.

questionAnswers(5)

yourAnswerToTheQuestion