Seite 1 von 2
Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 20:32
von Bluebay
Hallo.
Ich bin absoluter Python Anfänger und mache gerade meine ersten Schritte.
Ich möchte gerade den Inhalt zweier Textdateien vergleichen und das Ergebnis in eine dritte Datei schreiben. Beide Dateien enthalten in jeder Zeile einen Namen. Eine grosse Datei A mit allen bekannten Namen und eine kleinere Datei B mit neu hinzugekommenen Namen. In die dritte Datei C sollen nun alle neu hinzugekommenen Namen aus B geschrieben werden die in der grossen Datei A noch nicht enthalten sind.
Das bekomme ich noch nicht ganz gebacken. Ich habe folgendes probiert:
Code: Alles auswählen
with open('A') as big, open('B') as small, open('C', 'w') as new:
new.writelines(line for line in small if line not in set(big))
Das funktioniert aber ganz und gar nicht wie es soll.
Weiss jemand Rat?
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 20:37
von BlackJack
@Bluebay: Die Bedingung wird für jede Zeile in `small` ausgeführt. Überleg mal was passiert wenn man `set(big)` mehrmals ausführt, also insbesondere bei jedem mal ausser dem ersten mal.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 20:46
von Bluebay
Ich bin gerade auf dem Level mit raw_input und print. Deine Frage überfordert mich leider noch komplett.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 20:51
von BlackJack
@Bluebay: Wie bist Du denn dann auf diese Zeile gekommen? Schreib das mal selber, so dass Du auch verstehst was da passiert. Und probiere einfach mal aus was passiert wenn man `set()` zweimal hintereinander auf das selbe Dateiobjekt anwendet, was da jeweils als Ergebnis kommt.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 21:22
von Bluebay
Ich bin von meinem Python Online Kurs einfach ein wenig abgewichen und will die mir selbst gestellte Aufgabe jetzt umsetzen. Kannst du mir einen Tip geben in welcher Richtung ich suchen / lesen muss? Den Code habe ich aus dem Web und wenn er wie gewünscht funktionieren würde, hätte ich versucht ihn zu verstehen und ihn zu erweitern. So lerne ich meistens ganz gut.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 21:37
von /me
Bluebay hat geschrieben:Den Code habe ich aus dem Web und wenn er wie gewünscht funktionieren würde, hätte ich versucht ihn zu verstehen und ihn zu erweitern.
Nun funktioniert der Code aber nicht und es ist folglich um so wichtiger, dass du ihn verstehst.
Wir sollten uns da jetzt echt mal durcharbeiten. Was macht denn die erste Zeile?
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 22:05
von Bluebay
Die erste Zeile öffnet alle 3 Dateien und weist ihrem Inhalt Variablen zu. C wird beschreibbar geöffnet.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 22:09
von Sirius3
@Bluebay: was meinst Du mit Inhalt?
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 23:43
von Bluebay
Damit meine ich die Zeichen und Zeichenketten in den jeweiligen Dateien.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Montag 14. April 2014, 23:45
von BlackJack
@Bluebay: Dann stimmt das schon mal nicht, denn in der ersten Zeile wird mit den Bytes in den Dateien noch gar nichts gemacht.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Dienstag 15. April 2014, 08:27
von /me
Bluebay hat geschrieben:Damit meine ich die Zeichen und Zeichenketten in den jeweiligen Dateien.
Nicht so ganz. Die Dateien werden zwar geöffnet, aber nicht gelesen.
Gelesen werden sie, wenn die Daten auf dem Dateiobjekt abgerufen werden. Das kann explizit mit einer Schleife passieren (
for line in small) oder auch implizit (
set(big)).
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Dienstag 15. April 2014, 08:50
von snafu
@Bluebay
Um mal ein bißchen was vorweg zu nehmen: Dateiobjekte haben einen Positionszeiger. Nach dem Öffnen einer Datei - d.h. nachdem das Dateiobjekt z.B. mittels `open()` erstellt wurde - steht dieser Positionszeiger vor dem ersten Zeichen. Durch jede Aktion, die dazu führt, dass die Datei komplett durchlaufen wird (Schleife über alle Zeilen, Suchen eines Textabschnitts, Verwendung des Dateiobjekts mit `set()`, `list()`, `tuple()`, ...), steht dieser Zeiger am Ende der Aktion auf der Position hinter dem letzten Zeichen - und dort verbleibt er. Die Konsequenz daraus ist, dass jeder weitere `set()`-Aufruf in deinem Code bei seiner "Abfrage" gegenüber dem Dateiobjekt keine weiteren Zeichen mehr erhält, da der Postionszeiger eben vor keinem weiteren Zeichen mehr steht und somit nichts weiteres ausgeliefert werden kann. Weitere `set`-Objekte werden folglich *immer* leer bleiben. Dies ist sicherlich nicht das Verhalten, welches du bzw der Ersteller deines Codes im Sinn hatten.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Dienstag 15. April 2014, 08:58
von BlackJack
Oder mal in einer Python-Shell demonstriert:
Code: Alles auswählen
In [41]: !cat test.txt
one
two
three
In [42]: f = open('test.txt')
In [43]: set(f)
Out[43]: {'one\n', 'three\n', 'two\n'}
In [44]: set(f)
Out[44]: set()
In [45]: set(f)
Out[45]: set()
In [46]: f.close()
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Mittwoch 16. April 2014, 19:31
von Bluebay
Ist ja viel Overhead.
In der Bash löse ich es einfach mit
Ich dachte das es in Python eine ähnlich simple Variante gäbe.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Mittwoch 16. April 2014, 19:43
von BlackJack
@Bluebay: Ein fertiges Programm benutzen ist einfacher als so ein Programm selber zu schreiben. Wer hätte das gedacht.
Wieso sollte das in einer allgemeinen Programmiersprache, mit der man so ziemlich alles machen kann, ”simpler” sein als mit einem auf diesen Anwendungsfall spezialisierten Programm? Zumal das semantisch nicht äquivalent ist, denn in A stehen reguläre Ausdrücke wo es Zeichen mit besonderer Bedeutung gibt.
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Mittwoch 16. April 2014, 20:00
von Bluebay
BlackJack hat geschrieben:@Bluebay: Ein fertiges Programm benutzen ist einfacher als so ein Programm selber zu schreiben. Wer hätte das gedacht.
Ja da hast du recht. War nicht unbedingt schlau der Post. Kann mir vielleicht jemand den richtigen Code posten, damit ich mich damit auseinandersetzen kann?
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Mittwoch 16. April 2014, 20:10
von Hyperion
Bluebay hat geschrieben:
Kann mir vielleicht jemand den richtigen Code posten, damit ich mich damit auseinandersetzen kann?
Wie wäre es, wenn Du den selber *entwickelst*; besser kann man sich mit einem Problem nicht auseinander setzen!

(Und ja, Hilfe dazu gibt es hier - fertige Lösungen eher seltener...)
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Mittwoch 16. April 2014, 20:44
von Hyperion
Hier mal ein Ansatz in Clojure (ohne Laden aus Dateien!):
Code: Alles auswählen
user=> (use 'clojure.set)
nil
user=> (def large #{"John Schnee" "Margaery Tyrell" "Robb Stark"})
#'user/large
user=> (def small #{"Tyrion Lannister" "John Schnee"})
#'user/small
user=> (difference small large)
#{"Tyrion Lannister"}
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Mittwoch 16. April 2014, 21:03
von BlackJack
C++ mit dem neuen `unordered_set` und laden aus Dateien:
Code: Alles auswählen
#include <fstream>
#include <string>
#include <unordered_set>
using namespace std;
int main()
{
string line;
ifstream big_file("A");
unordered_set<string> big;
while (getline(big_file, line)) {
big.insert(line);
}
big_file.close();
ifstream small_file("B");
ofstream out_file("C");
while (getline(small_file, line)) {
if (big.find(line) == big.end()) {
out_file << line << endl;
}
}
out_file.close();
small_file.close();
return 0;
}
Re: Python Anfänger - Dateiinhalt vergleichen
Verfasst: Mittwoch 16. April 2014, 22:01
von Hyperion
Noch einmal Clojure mit dem Lesen aus Dateien:
Code: Alles auswählen
(use 'clojure.set)
(use '[clojure.string :only (split)])
(def small (apply hash-set (split (slurp "small.txt") #"\n")))
(def large (apply hash-set (split (slurp "large.txt") #"\n")))
(println (difference small large))