Umgang 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 eineStopIteration-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).
1234567891011log_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}")
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')
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?
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen
Awesome!
Completion rate improved to 7.69
Umgang 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 eineStopIteration-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).
1234567891011log_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}")
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')
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?
Danke für Ihr Feedback!