Нет необходимости читать весь входной файл в память. Все, что вам действительно нужно, это знать количество строк. Давайте предположим, что вы уже знаете это, и назовите это n
. (При необходимости вы можете вычислить это в отдельном проходе файла). Теперь, когда вы читаете входные данные, вы можете выбрать, в какой файл писать с вероятностью, связанной с числом выбранных вами случайных строк.
import random
with open('bigfile.txt', 'r') as f, \
open('split1.txt', 'w') as a, \
open('split2.txt', 'w') as b:
# Compute number of lines, if necessary
for size, _ in enumerate(f, start=1):
pass
f.seek(0) # Start over
for line in f:
out = random.choices([a, b], [n, size - n])
if out is a:
n -= 1
size -= 1
out.write(line)
Вы можете доказать, что это дает каждую строку такая же вероятность быть выбранной для файла a
. Интуитивно понятно, что каждый раз, когда вы выбираете линию, вероятность выбора более поздней линии уменьшается, потому что доступно меньше свободных «слотов». В то же время, когда вы читаете файл, вероятность увеличивается, потому что остается меньше вариантов для заполнения оставшихся слотов. В крайнем случае, вы перестанете выбирать линии, когда n
достигнет 0, и вы всегда будете выбирать линию один раз n == size
.
Если у вас есть даже приблизительная оценка того, что size
должно быть Вы, вероятно, можете использовать это вместо чтения всего файла, чтобы вычислить его точный размер, не слишком отклоняясь от истинного равномерного распределения.