TGViewer
Python Заметки Python Заметки @pythonotes · 2.2K subscribers
Post #302 2.41K
😋 Заметка от читателя @nencoru

Как смержить несколько файлов с отсортированными строками в один файл, тоже отсортированный?

🔸 Исходный файл:

▫️ в одной строке находится одна запись
▫️ запись содержит предсказуемое поле с некими данными для сортировки. Например, логи с указанием времени.
▫️ все записи в файле отсортированы по этому полю

🔸 Задача:

Смержить несколько таких файлов так, чтобы в финальном файле все записи были также отсортированы.

🔸 Решение 1:

Предположим, у меня JSON-логи

files = ['file1.jsonl', 'file2.jsonl', ...]

data = []
for file in files:
with open(file) as f:
data.expand(
f.readlines()
)
data.sort(key=lambda line: json.loads(line)['timestamp'])
with open('merged.jsonl', 'w') as f:
f.writelines(data)

Усложним задачу — размер каждого файла 5Gb 😱

Это означает, что вам потребуется оперативной памяти 5*len(files) Gb.
И уже не каждый компьютер сможет смержить 3-4 таких файла. А если их 100?

fileinput может помочь написать более красивый код, но с памятью не поможет.

🔸 Решение 2:

Можно использовать готовую функцию heapq.merge() из стандартного модуля heapq!

Heap - это бинарное дерево, где каждый родительский элемент в дереве имеет значение меньшее чем дочерний.

То есть, по умолчанию все элементы как-либо отсортированы.

from heapq import merge
items = [
[3,2,6],
[1,5,4]
]
print(list(merge(*items)))
# [1, 2, 3, 4, 5, 6]

А учитывая, что merge это генератор, умеет работать с файлами и ему можно передать функцию для сортировки, он отлично подойдет для нашей задачи, так как полной загрузки в память не происходит!

И тут вы спросите: что за магия?
Тоже самое только без расхода памяти? Волшебный генератор всех спасёт?

Нет, за всё приходится платить. В случае с heapq весь процесс драматически замедлится.
Но задача будет выполнена! 😎

Сделал для вас синтетический пример для генерации и мержа подобных файлов
Код смотреть здесь ↗️

▫️ make_logs() генерит 30 файлов по 50Mb для теста
▫️ merge_list() мержит файлы через простой список
▫️ merge_heapq() мержит файлы через heapq
▫️ memory_profiler считает используемую память (нужно установить модуль)
▫️ также есть замер времени

Кому лениво там же смотрите мои тесты:

1.5Gb и 19.5с против 19Mb и 2м 43с
памяти в 80 раз меньше, но времени в 8 раз больше

⚠️ ВАЖНО
для чистоты эксперимента запускать следует из консоли и по одному тесту на процесс. То есть закоментили второй, запустили первый, закоментили первый, запустили второй.

#bacik
Gist Merging of huge sorted files Merging of huge sorted files. GitHub Gist: instantly share code, notes, and snippets.
  • 👍 3
More from @pythonotes
  1. Sep 21, 2026­ WebAssembly это мощная технология позволяющая загружать практически любое приложение в б…
  2. Aug 17, 2026Не так давно столкнулся с API который в ответе с ошибкой присылал только статус-код. Без п…
  3. Jul 20, 2026У меня основная ОС это Linux. Но нередко требуется делать сборку клиента под Windows. Соби…
  4. Jul 13, 2026В прошлый раз был пример с понижением привелегий процесса. Проблема в том, что обратно под…
  5. Jul 6, 2026Модуль pwd может использоваться для считывания информации о пользователях из базы данных п…
  6. Jun 22, 2026Недавно я реализовал Multi Tenancy систему на FastAPI + SQLAlchemy и пересобрал её в небол…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →