Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Обробка Великих Файлів | Підвищення Продуктивності За Допомогою Вбудованих Інструментів
Техніки Оптимізації в Python

bookОбробка Великих Файлів

Свайпніть щоб показати меню

Ефективна обробка великих файлів є важливою при роботі з наборами даних, які занадто великі для розміщення в оперативній пам'яті. Python надає інструменти, такі як open() та map(), які дозволяють обробляти файли ліниво, економлячи пам'ять і підвищуючи продуктивність.

Що таке ітератори?

Перш ніж перейти до функції open(), слід спочатку зрозуміти, що таке ітератор. Ітератор — це об'єкт, який представляє потік даних і дозволяє отримувати по одному елементу за раз. Ітератори реалізують два методи:

  • __iter__(): повертає сам об'єкт ітератора;
  • __next__(): повертає наступний елемент потоку та викликає виняток StopIteration, коли елементи закінчуються.

Припустимо, у нас є ітератор з назвою iterator_object. Ми можемо перебирати його за допомогою звичайного циклу for:

for element in iterator_object:
    ...  # Process the element

Насправді, під капотом відбувається наступне (функція next() внутрішньо викликає метод __next__() ітератора):

while True:
    try:
        element = next(iterator_object)
        ...  # Process the element
    except StopIteration:
        break

На відміну від стандартних колекцій, ітератори характеризуються лінивою оцінкою (lazy evaluation), тобто вони генерують або отримують дані лише за потреби, а не завантажують усе в пам'ять одразу. Такий підхід робить їх дуже ефективними щодо використання пам'яті, особливо при роботі з великими наборами даних.

Файлові об'єкти як ітератори

Функція open() повертає файловий об'єкт, який є ітератором. Це дозволяє:

  • Перебирати файл построчно за допомогою циклу for;
  • Зчитувати по одному рядку за раз у пам'ять, що робить цей підхід придатним для великих файлів (за умови, що окремі рядки поміщаються в пам'ять).

Наприклад, якщо у файлі журналу з 1,000,000 рядків містяться як повідомлення INFO, так і ERROR, ми все одно можемо підрахувати кількість входжень ERROR, перебираючи файл построчно, навіть якщо файл повністю не поміщається в пам'ять (що ймовірно, якщо додати ще більше записів у журнал).

1234567891011
log_lines = [f"INFO: Log entry {i}" if i % 100 != 0 else f"ERROR: Critical issue {i}" for i in range(1, 1000001)] with open("large_log.txt", "w") as log_file: log_file.write("\n".join(log_lines)) # Process the file to count error entries error_count = 0 for line in open("large_log.txt"): if "ERROR" in line: error_count += 1 print(f"Total error entries: {error_count}")
copy

Перетворення рядків файлу за допомогою map()

Як зазначено у попередньому розділі, map() повертає ітератор, ліниво застосовуючи функцію перетворення до кожного рядка у файлі. Подібно до файлових об'єктів, map() обробляє дані по одному елементу, не завантажуючи все у пам'ять, що робить його ефективним варіантом для роботи з великими файлами.

Наприклад, створимо файл, що містить 1000000 електронних адрес, деякі з яких містять великі літери. Мета — перетворити всі адреси на малі літери та зберегти нормалізовані результати у новий файл ('normalized_emails.txt'). Для цього використаємо map(), що забезпечить ефективність скрипта навіть для ще більших файлів.

12345678910111213141516171819202122
# Create a file with mixed-case email addresses email_lines = [ "John.Doe@example.com", "Jane.SMITH@domain.org", "BOB.brown@anotherexample.net", "ALICE.williams@sample.com" ] * 250000 # Repeat to simulate a large file with open("email_list.txt", "w") as email_file: email_file.write("\n".join(email_lines)) # Process the file to standardize email addresses (convert to lowercase) with open("email_list.txt") as input_file, open("normalized_emails.txt", "w") as output_file: # Use map() to convert each email to lowercase lowercase_emails = map(str.lower, input_file) for email in lowercase_emails: output_file.write(email) # Print the last email to verify the results print(email) print('Done')
copy

1. Потрібно перетворити всі електронні адреси у файлі на нижній регістр і зберегти їх у новий файл без завантаження всього вмісту у пам'ять. Який підхід є найбільш ефективним?

2. Яке з наведених тверджень про файлові об'єкти є правильним?

question mark

Потрібно перетворити всі електронні адреси у файлі на нижній регістр і зберегти їх у новий файл без завантаження всього вмісту у пам'ять. Який підхід є найбільш ефективним?

Select the correct answer

question mark

Яке з наведених тверджень про файлові об'єкти є правильним?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 3. Розділ 2

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Секція 3. Розділ 2
some-alt