Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Umgang mit Großen Dateien | Enhancing Performance With Built-in Tools
Optimierungstechniken in Python

bookUmgang mit Großen Dateien

Die effiziente Verarbeitung großer Dateien ist entscheidend, wenn mit Datensätzen gearbeitet wird, die zu groß für den Arbeitsspeicher sind. Python stellt Werkzeuge wie open() und map() bereit, die eine verzögerte Verarbeitung von Dateien ermöglichen, wodurch Speicher gespart und die Leistung verbessert wird.

Was sind Iteratoren?

Bevor die Funktion open() betrachtet wird, sollte zunächst geklärt werden, was ein Iterator ist. Ein Iterator ist ein Objekt, das einen Datenstrom repräsentiert und den Zugriff auf jeweils ein Element ermöglicht. Iteratoren implementieren zwei Methoden:

  • __iter__(): Gibt das Iterator-Objekt selbst zurück;
  • __next__(): Gibt das nächste Element im Datenstrom zurück und löst eine StopIteration-Ausnahme aus, wenn keine Elemente mehr vorhanden sind.

Angenommen, es gibt einen Iterator namens iterator_object. Über diesen kann mit einer üblichen for-Schleife iteriert werden:

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

Tatsächlich geschieht im Hintergrund Folgendes (die Funktion next() ruft intern die Methode __next__() des Iterators auf):

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

Im Gegensatz zu Standardkollektionen zeichnen sich Iteratoren durch Lazy Evaluation aus, das heißt, sie erzeugen oder holen Daten nur bei Bedarf und laden nicht alles auf einmal in den Speicher. Dieser Ansatz macht sie besonders speichereffizient, insbesondere bei der Arbeit mit großen Datensätzen.

Dateiobjekte als Iteratoren

Die Funktion open() gibt ein Dateiobjekt zurück, das ein Iterator ist. Dadurch ist es möglich:

  • Mit einer for-Schleife zeilenweise durch eine Datei zu iterieren;
  • Jeweils nur eine Zeile in den Speicher zu laden, was die Verarbeitung von großen Dateien ermöglicht (sofern einzelne Zeilen in den Speicher passen).

Enthält beispielsweise eine Protokolldatei mit 1,000,000 Zeilen sowohl INFO- als auch ERROR-Meldungen, können dennoch die ERROR-Vorkommen gezählt werden, indem die Datei zeilenweise durchlaufen wird – selbst wenn die Datei nicht vollständig in den Speicher passt (was der Fall ist, wenn noch deutlich mehr Protokolle hinzukommen).

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

Umwandlung von Dateizeilen mit map()

Wie im vorherigen Kapitel erwähnt, gibt map() einen Iterator zurück, der eine Transformationsfunktion verzögert auf jede Zeile einer Datei anwendet. Ähnlich wie Dateiobjekte verarbeitet map() die Daten ein Element nach dem anderen, ohne alles in den Speicher zu laden. Dadurch ist es eine effiziente Option für die Verarbeitung großer Dateien.

Beispielsweise soll eine Datei mit 1000000 E-Mail-Adressen erstellt werden, von denen einige Großbuchstaben enthalten. Ziel ist es, alle E-Mails in Kleinbuchstaben umzuwandeln und die normalisierten Ergebnisse in einer neuen Datei ('normalized_emails.txt') zu speichern. Hierzu wird map() verwendet, sodass das Skript effizient bleibt und sich auch für noch größere Dateien eignet.

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. Sie müssen alle E-Mail-Adressen in einer Datei in Kleinbuchstaben umwandeln und in einer neuen Datei speichern, ohne alles in den Speicher zu laden. Welcher Ansatz ist am effizientesten?

2. Welche der folgenden Aussagen über Dateiobjekte ist korrekt?

question mark

Sie müssen alle E-Mail-Adressen in einer Datei in Kleinbuchstaben umwandeln und in einer neuen Datei speichern, ohne alles in den Speicher zu laden. Welcher Ansatz ist am effizientesten?

Select the correct answer

question mark

Welche der folgenden Aussagen über Dateiobjekte ist korrekt?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 2

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

Awesome!

Completion rate improved to 7.69

bookUmgang mit Großen Dateien

Swipe um das Menü anzuzeigen

Die effiziente Verarbeitung großer Dateien ist entscheidend, wenn mit Datensätzen gearbeitet wird, die zu groß für den Arbeitsspeicher sind. Python stellt Werkzeuge wie open() und map() bereit, die eine verzögerte Verarbeitung von Dateien ermöglichen, wodurch Speicher gespart und die Leistung verbessert wird.

Was sind Iteratoren?

Bevor die Funktion open() betrachtet wird, sollte zunächst geklärt werden, was ein Iterator ist. Ein Iterator ist ein Objekt, das einen Datenstrom repräsentiert und den Zugriff auf jeweils ein Element ermöglicht. Iteratoren implementieren zwei Methoden:

  • __iter__(): Gibt das Iterator-Objekt selbst zurück;
  • __next__(): Gibt das nächste Element im Datenstrom zurück und löst eine StopIteration-Ausnahme aus, wenn keine Elemente mehr vorhanden sind.

Angenommen, es gibt einen Iterator namens iterator_object. Über diesen kann mit einer üblichen for-Schleife iteriert werden:

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

Tatsächlich geschieht im Hintergrund Folgendes (die Funktion next() ruft intern die Methode __next__() des Iterators auf):

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

Im Gegensatz zu Standardkollektionen zeichnen sich Iteratoren durch Lazy Evaluation aus, das heißt, sie erzeugen oder holen Daten nur bei Bedarf und laden nicht alles auf einmal in den Speicher. Dieser Ansatz macht sie besonders speichereffizient, insbesondere bei der Arbeit mit großen Datensätzen.

Dateiobjekte als Iteratoren

Die Funktion open() gibt ein Dateiobjekt zurück, das ein Iterator ist. Dadurch ist es möglich:

  • Mit einer for-Schleife zeilenweise durch eine Datei zu iterieren;
  • Jeweils nur eine Zeile in den Speicher zu laden, was die Verarbeitung von großen Dateien ermöglicht (sofern einzelne Zeilen in den Speicher passen).

Enthält beispielsweise eine Protokolldatei mit 1,000,000 Zeilen sowohl INFO- als auch ERROR-Meldungen, können dennoch die ERROR-Vorkommen gezählt werden, indem die Datei zeilenweise durchlaufen wird – selbst wenn die Datei nicht vollständig in den Speicher passt (was der Fall ist, wenn noch deutlich mehr Protokolle hinzukommen).

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

Umwandlung von Dateizeilen mit map()

Wie im vorherigen Kapitel erwähnt, gibt map() einen Iterator zurück, der eine Transformationsfunktion verzögert auf jede Zeile einer Datei anwendet. Ähnlich wie Dateiobjekte verarbeitet map() die Daten ein Element nach dem anderen, ohne alles in den Speicher zu laden. Dadurch ist es eine effiziente Option für die Verarbeitung großer Dateien.

Beispielsweise soll eine Datei mit 1000000 E-Mail-Adressen erstellt werden, von denen einige Großbuchstaben enthalten. Ziel ist es, alle E-Mails in Kleinbuchstaben umzuwandeln und die normalisierten Ergebnisse in einer neuen Datei ('normalized_emails.txt') zu speichern. Hierzu wird map() verwendet, sodass das Skript effizient bleibt und sich auch für noch größere Dateien eignet.

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. Sie müssen alle E-Mail-Adressen in einer Datei in Kleinbuchstaben umwandeln und in einer neuen Datei speichern, ohne alles in den Speicher zu laden. Welcher Ansatz ist am effizientesten?

2. Welche der folgenden Aussagen über Dateiobjekte ist korrekt?

question mark

Sie müssen alle E-Mail-Adressen in einer Datei in Kleinbuchstaben umwandeln und in einer neuen Datei speichern, ohne alles in den Speicher zu laden. Welcher Ansatz ist am effizientesten?

Select the correct answer

question mark

Welche der folgenden Aussagen über Dateiobjekte ist korrekt?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 2
some-alt