Python zwei TXT Dateien vergleichen und ergänzen?

4 Antworten

Hallo nochmal!
Im ersten Posting habe ich wahrscheinlich dein Problem falsch verstanden, lasse aber dennoch das Posting mal stehen.

Den Vergleich der zwei Arrays habe ich dir mal ausprogrammiert.

Dabei werden die Worte der Datei2 als Array Values durchlaufen Dabei wird geschaut ob dieser Wert in dem Datei1 Array bereits vorhanden ist, falls nicht wird das Wort aus Datei2 in dem Array der Datei1 ergänzt. Hierdurch vergrößert sich das Array der Datei1 um ein zu prüfendes Wort, welches nicht nochmals hineingeschrieben wird.

import array

Datei1Worte = ["apfel", "birne", "banane"];
Datei2Worte = ["apfel", "banane","erdbeere", "erdbeere", "pflaume"];

for elem in Datei2Worte:
existElem = False;
for el in Datei1Worte:
print("Elem: "+ elem + " vergleicht " + el);
if(elem == el):
print("\t"+ el +" bereits vorhanden");
#Element bereits vorhanden
existElem = True;
break;
if(existElem == False):
Datei1Worte.append(elem);
print(Datei1Worte);
print("-----");
print(Datei2Worte);

Löst dies dein Problem?

MfG

Norman Fober

romanmiller 
Fragesteller
 23.06.2017, 16:07

Hab es noch nicht probiert, aber du kannst ja mal meine Kommentare unter der anderen Antwort lesen. Trotzdem danke dafür :)

0
Noha1981  23.06.2017, 19:41
@romanmiller

Ok, es scheint Performance Probleme zu geben.
Die Größe der Datei sollte Python egal sein.
Mein obiges (Teil-)Skript besitzt eine Laufzeit von O(n*m) (ist immer der Worst-Case). Das heißt bei jeweils n,m=3000 Passwörtern haben wir bereits 9.000.000 Vergleiche. Ab dem 8-9 stelligen Bereich wird es für normale Computer schwerer.
Wenn du aber eh eine so große Datenmenge besitzt, würde ich dir eher die nutzung einer Datenbank empfehlen!
Hier sind die Suchen über Indizierung deutlich schneller!

MfG
Norman Fober

0
romanmiller 
Fragesteller
 24.06.2017, 14:14

Naja, vielleicht hast du Recht. Da müsste ich mich halt mal informieren, wie ich das mit Python dann manage. Danke :)

0
TeeTier  25.06.2017, 03:43

Oder so:

a = ["apfel", "birne", "banane"]
b = ["apfel", "banane", "erdbeere", "erdbeere", "pflaume"]

c = list(sorted(set(a + b)))
print('\n'.join(c))
0
TeeTier  25.06.2017, 03:50

Zusatz: Falls - wie in der Frage erwünscht - NUR die Wörter aus Datei 2 ans Ende von Datei 1 rangehängt werden sollen, die NICHT schon in Datei 1 existieren, dann einfach so:

a = ["apfel", "birne", "banane"]
b = ["apfel", "banane", "erdbeere", "erdbeere", "pflaume"]

a += list(set(b) - set(a))
print(a)

Danach enthält a:

['apfel', 'birne', 'banane', 'erdbeere', 'pflaume']

Wobei es keine Sortierung gibt, weder von den ursprünglichen Wörtern aus "a", noch von den angehängten aus Gruppe "b".

Naja, muss der Fragensteller selber wissen, was er sich aus den ganzen Anregungen zusammen bauen will. :)

0
Noha1981  25.06.2017, 16:28
@TeeTier

Jap, mit der Sortierung der vorigen Listen wäre ein Möglichkeit.
Sobald ein zu prüfender Wert größer des Suchwertes ist, kann die Suche als erfolglos abgebrochen werden und der Wert folglich angefügt werden.

0

Ich schreibe einfach noch meine Eigene Antwort zu.

file1 = open("file1.txt").read().split("\n")
file2 = open("file2.txt").read().split("\n")
addto = {"file1": [], "file2": []}

for item in file1:
    if not item in file2:
        addto["file2"].append(item)

for item in file2:
    if not item in file1:
        addto["file1"].append(item)

for n in range(1, 3):
with open("file%i.txt" % n, "w") as file:
    for item in addto["file%i" % n]:
        file.write("\n" + item)

#Code von Tbear44

Das funktioniert, auch wenn's bei SEHR großen Dateien bisschen dauert.

Woher ich das weiß:Hobby – Ich programmiere sehr gerne und häufig.

Also mit anderen Worten: Du willst die Wörter aus Datei A und Datei B sortiert in einer Datei C (oder von mir aus auch wieder in einer der Eingangs-Dateien A oder B) vereinen?

So etwas vielleicht:
from codecs import open as co
import re

pattern = re.compile('\w+')

words = set()
for infile in ('a.txt', 'b.txt'):
with co(infile, 'r', 'utf-8', 'strict') as fp:
for line in fp:
for match in pattern.finditer(line):
words.add(match.group())

with co('words.txt', 'w', 'utf-8', 'strict') as fp:
for word in sorted(words):
fp.write(word + '\n')

Da ich nicht weiß, in welcher Form deine Dateien vorliegen, habe ich einfach einen regulären Ausdruck zum iterieren über die einzelnen Wörter genommen.

Falls also die Datei "a.txt" diesen Inhalt hat:

ab cd ef
gh ij kl mn

... und die Datei "b.txt" so einen Inhalt:

cd gh
ij mn
xy

... dann steht als Resultat in der Datei "words.txt" das hier:

ab
cd
ef
gh
ij
kl
mn
xy

Naja, viel Spaß damit! :)

PS: Das obige Beispiel setzt auf Python 3, aber in Python 2 ist es auch mit wenigen Anpassungen lauffähig. :)

TeeTier  25.06.2017, 03:34

PS: Natürlich sollte man bei einer so auffällig tiefen Verschachtelung der Ordnung zu Liebe Funktionen einführen, aber es ist ja sowieso nur ein Snippet, von daher ... ><

PPS: Im Übrigen ist eine ganz normale Unix Shell mit den gängigen Standardwerkzeugen für die meisten solcher einfachen Textdatei-Aufgaben deutlich besser geeignet, als Python!

Das ganze obige Python Snippet sähe als sh-Skript so aus:
grep -ohP '\w+' a.txt b.txt | sort -u >words.txt

Wesentlich kürzer, leistet aber exakt das Selbe! Auch wenn du Windows benutzt, solltest du dir vielleicht mal eine Unixoide Shell wie die Bash installieren, falls du öfter mal mit so ähnlichen Problemen, wie dem aus deiner Frage, zu kämpfen hast.

In vermutlich 95% aller Fälle kommst du bei kleinen und überschaubaren Problemen mit einem Shell-Skript bzw. einem Einzeiler schneller und besser ans Ziel, als mit Python, Ruby oder Perl. Ist zumindest bei mir so. Eine ausgewachsene Skriptsprache setze ich eigentlich nur dann ein, wenn es größer wird und "hübsch" sein muss. :)

0

Hallo Roman Miller!

Ohne es jetzt direkt auszuprogrammieren, abstrahiere ich dein Problem mal ein wenig.

Gegeben:

  • 2 verschiedene Textdateien
  • wobei die AnzWorte(Datei1) <= AnzWorte(Datei2) ist
  • wobei Worte(Datei1) eine geordnete Teilmenge von Worte(Datei2) sind.

Algorithmus

  1. lese per split() die Worte aus Datei1 und Datei2
  2. speichere die Worte in einzelne Arrays (Dat1[Worte], Dat2[Worte])
  3. Durchlaufe die Arrays und vergleiche Dat1[i] == Dat2[j]
  4. Wenn 3 wahr ist, schreibe Dat1[i] in die neue Datei
  5. Wenn 3 falsch ist, solange Dat2[j] != Dat1[i] schreibe Dat2[j] in die neue Datei
  6. Wenn Dat1[i] EOF erreicht hat, füge den Rest von Dat2[j] an

Fazit:

Möglicher Weise hört es sich so abstrahiert etwas kompliziert an, aber wenn obige Vorraussetzungen (ich also dein Problem richtig verstanden habe) erfüllt sind, müsste es so gehen!

Ich hoffe, das ich dir helfen konnte!

MfG

Norman Fober