Seite 1 von 1
Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 09:49
von mzh
Hallo zusammen
Ich versuche die ersten Zeichen in zwei Files auf Gleichheit zu überprüfen. Die Files sehen so aus:
- setup keywords 1
Title1
comment1
N( 1 PRO* 1) 0.01245965 +1 0.07673554 +1 -0.05772082 +1 -0.4053
C( 2 PRO* 1) 1.50693114 +1 0.02121969 +1 -0.01874981 +1 -0.1167
C( 3 PRO* 1) 2.10882265 +1 1.42991342 +1 -0.05147952 +1 0.5845
[...]
und genau so für das zweite File.
Mein Code sieht nun so aus:
Code: Alles auswählen
#!/usr/bin/env python
import os, sys
file1 = open(sys.argv[1])
file2 = open(sys.argv[2])
data1 = file1.readlines()
data2 = file2.readlines()
control = map(lambda x, y: x.split()[0] == y.split()[0], data1[:-1], data2[:-1])
Dh. der Witz ist, dass ich so kontrollieren kann, das in beiden Files die Elemente in der gleichen Reihenfolge stehen.
Eine Frage nun: angenommen eine Zeile ist leer, dann crashed meine lambda Funktion. Wie kann ich das abfangen? data1[:-1] ist notwendig, weil eben die letzte Zeile gerade leer ist.
Re: Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 10:13
von sma
Anhand der `#!`-Zeile in einem Python-Programm schließe ich, dass du etwas unix-artiges als Betriebssystem nutzt. Warum benutzt du da nicht einfach `diff`? Und dreht sich
http://python-forum.de/viewtopic.php?f=11&t=22856 nicht um die selbe Frage?
Hier ein Schnellschuss von mir. Da sich zip() nicht so verhielt, wie ich dachte, habe ich einfach meine eigene Version davon geschrieben, die allerdings recht umständlich aussieht.
Code: Alles auswählen
with open("/tmp/a") as a, open("/tmp/b") as b:
def zip(x, y):
x = iter(x)
y = iter(y)
while True:
xe, ye = False, False
try:
xx = next(x)
except:
xx = "\n"
xe = True
try:
yy = next(y)
except:
yy = "\n"
ye = True
if xe and ye:
break
yield xx, yy
line = 0
for la, lb in zip(a, b):
line += 1
if la != lb:
print("Unterschied in %s:" % line)
print(repr(la))
print(repr(lb))
break
else:
print("alles gleich")
Stefan
Re: Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 10:21
von EyDu
@sma: ich glaube du suchst
itertools.izip_longest.
Re: Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 10:31
von sma
Exakt. Ich wusste doch, das geht besser:
Code: Alles auswählen
with open("/tmp/a") as a, open("/tmp/b") as b:
from itertools import zip_longest
line = 0
for la, lb in zip_longest(a, b, fillvalue="\n"):
line += 1
if la != lb:
print("Unterschied in %s:" % line)
print(repr(la))
print(repr(lb))
break
else:
print("alles gleich")
Stefan
Re: Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 10:45
von BlackJack
Ich würde ja noch das manuelle hochzählen von `line` durch `enumerate()` ersetzen.
Code: Alles auswählen
with open("/tmp/a") as a, open("/tmp/b") as b:
from itertools import count, zip_longest
for line, (la, lb) in enumerate(zip_longest(a, b, fillvalue="\n")):
if la != lb:
print("Unterschied in %s:" % (line + 1))
print(repr(la))
print(repr(lb))
break
else:
print("alles gleich")
Re: Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 13:01
von mzh
danke für die hinweise.
Ja, das ist dasselbe wie ich schon mal gepostet habe. Wollte einfach meine neuste Lösung präsentieren.
Muss mir die Vorschläge aber zuerst genau anschauen. Auf den ersten Blick sehe ich aber nicht, wieso mein Vorschlag nicht auch berechtigt sein soll.
So wie ich das verstehe ich difflib dann empfehlenswert, wenn z.B "Hochwasser" und "Hohcwaser" als ähnlich erkannt werden sollten. Bei mir findet aber keine User-Eingabe statt und somit sind die Fehlermöglichkeiten wirklich nur auf ein Zeichen eingeschränkt.
Und überhaupt, ich bin eigentlich nur schon froh, dass ich mal eine Situation mit lambda und map() angehen konnte

Re: Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 15:18
von noisefloor
Hallo,
folgende Lösung passt IMHO aber auch:
Code: Alles auswählen
datei1 = open('file1','r')
datei2 = open('file2','r')
comp1 = [a[0] for a in datei1 if a.strip()]
comp2 = [b[0] for b in datei2 if b.strip()]
if comp1 == comp2:
print "Stimmt"
else:
print "Stimmt nicht"
Gruß, noisefloor
Re: Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 15:26
von Dav1d
noisefloor, die Lösung funktioniert, solange die Datein ziemlich klein sind, sobald sie größer sind, gibts nen MemoryError
Re: Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 15:28
von ms4py
noisefloor hat geschrieben:folgende Lösung passt IMHO aber auch:
Nein

* Es fehlt ein `try..finally` bzw. `with`.
* Du überprüfst nur jeweils das erste Zeichen jeder Zeile.
* Diese Lösung ist DEUTLICH speicherhungriger und unperformanter.
Re: Vergleich von zwei Files
Verfasst: Mittwoch 12. Mai 2010, 23:54
von noisefloor
ms4py hat geschrieben:
* Es fehlt ein `try..finally` bzw. `with`
Stimmt. Ist mir hinterher eingefallen. Bzw. das zumindest `close` fehlt .
ms4py hat geschrieben:Du überprüfst nur jeweils das erste Zeichen jeder Zeile.
Ja, natürlich. Weil: Im 1. Posting steht "Ich versuche die ersten Zeichen in zwei Files auf Gleichheit zu überprüfen."
ms4py hat geschrieben: Diese Lösung ist DEUTLICH speicherhungriger und unperformanter.
Dafür einfacher zu verstehen.
Im Ernst: Wieso? Der Code braucht keinen Import-Statement, List Comprehension ist AFAIK ziemlich performant -> also woran liegst?
Gruß, noisefloor
Re: Vergleich von zwei Files
Verfasst: Donnerstag 13. Mai 2010, 08:01
von EyDu
Hallo.
noisefloor hat geschrieben:Stimmt. Ist mir hinterher eingefallen. Bzw. das zumindest `close` fehlt .

Der Hinweis auf try-finally, bzw with war schon angebracht. Wenn du zum Beispiel die erste Datei öffnest aber das Öffnen der zweiten fehlschlägt, dann wirst du dein close niemals erreichen.
noisefloor hat geschrieben:Im Ernst: Wieso? Der Code braucht keinen Import-Statement, List Comprehension ist AFAIK ziemlich performant -> also woran liegst?
Das Problem liegt darin, dass du alle Daten auf einmal mittels der LC einliest und diese gleichzeitig gehalten werden müssen. sma hingegen liest nur die Zeilen ein, die gerade verglichen werden sollen. Wenn zwei Zeilen sich unterscheiden, hört die Verarbeitung sofort auf.
Sebastian
Re: Vergleich von zwei Files
Verfasst: Donnerstag 13. Mai 2010, 09:04
von noisefloor
Hallo,
ok, verstehe. Es geht also nicht um die Laufzeit, sondern das, was im Speicher gehalten wird. So weit verstanden.
Andere Frage:
War die Anforderung ans Programm, dass Leerzeilen nicht als Unterschied gelten oder doch?
Also sollen z.B.
und
gleich sein oder nicht? Für sma's Variante ist es ein Unterschied, für meine nicht.
Gruß, noisefloor
Re: Vergleich von zwei Files
Verfasst: Donnerstag 13. Mai 2010, 20:27
von mzh
Hallo, danke für die Beiträge.
Zum letzten Post von noisefloor, Leerzeilen werden nicht vorkommen, weil das Datenformat diese nicht vorsieht (im Block mit den Koordinaten). Allerdings kommen evtl. am Anfang eine oder zwei Leerzeilen vor, wenn ein User keinen Titel setzt und keine Beschreibung angibt.
Was mich interessieren würde ist, wie ich diese Leerzeilen mit dem Code den ich gepostet habe, abfangen könnte, weil bei mir crashed das jeweils. Und ja, es geht eigentlich nur um das erste Zeichen bzw. String, weil dort das Element angegeben wird ('H', 'O', 'Cl', etc).
Re: Vergleich von zwei Files
Verfasst: Donnerstag 13. Mai 2010, 21:06
von BlackJack
@mzh: Du sagst immer das "crashed", was es aber sicher nicht tut. Es wird eine Ausnahme geben und die sollte Dir eigentlich sagen was da passiert. Falls nicht, probier die Operationen doch einfach mal Stück für Stück interaktiv auf einer leeren Zeichenkette. Spätestens dann sollte klar sein was passiert und damit auch was man dagegen tun kann.
Re: Vergleich von zwei Files
Verfasst: Donnerstag 13. Mai 2010, 21:48
von mzh
Code: Alles auswählen
Traceback (most recent call last):
File "/home/mzh/shellscripts/comp.py", line 21, in ?
control = map(lambda x, y: x.split()[0] == y.split()[0], data1[:-1], data2[:-1])
File "/home/mzh/shellscripts/comp.py", line 21, in <lambda>
control = map(lambda x, y: x.split()[0] == y.split()[0], data1[:-1], data2[:-1])
IndexError: list index out of range
ja, ich krieg schon mit, dass da ein IndexError auftritt, weil die Liste wohl leer sein wird, da es ja keine Zeichen auf einer leeren Zeile gibt. Es ist nicht split(), das scheitert, sondern split()[0] und ich weiss bis jetzt nicht, wie ich eine leere Zeile berücksichtigen kann (ich kann ja kein if statement in lambda einbauen oder doch?).
@BlackJack: hier ist es also notwendig, den IndexError abzufangen. Mein Ziel ist es jedenfalls, das ganze ohne for-loop zu erledigen.
Re: Vergleich von zwei Files
Verfasst: Donnerstag 13. Mai 2010, 22:32
von bords0
mzh hat geschrieben:Code: Alles auswählen
Traceback (most recent call last):
File "/home/mzh/shellscripts/comp.py", line 21, in ?
control = map(lambda x, y: x.split()[0] == y.split()[0], data1[:-1], data2[:-1])
File "/home/mzh/shellscripts/comp.py", line 21, in <lambda>
control = map(lambda x, y: x.split()[0] == y.split()[0], data1[:-1], data2[:-1])
IndexError: list index out of range
ja, ich krieg schon mit, dass da ein IndexError auftritt, weil die Liste wohl leer sein wird, da es ja keine Zeichen auf einer leeren Zeile gibt. Es ist nicht split(), das scheitert, sondern split()[0] und ich weiss bis jetzt nicht, wie ich eine leere Zeile berücksichtigen kann (ich kann ja kein if statement in lambda einbauen oder doch?).
@BlackJack: hier ist es also notwendig, den IndexError abzufangen. Mein Ziel ist es jedenfalls, das ganze ohne for-loop zu erledigen.
Mal [:1] statt [0] versuchen?
Re: Vergleich von zwei Files
Verfasst: Donnerstag 13. Mai 2010, 23:19
von mzh
Danke, das ist sehr hilfreich.
Re: Vergleich von zwei Files
Verfasst: Freitag 14. Mai 2010, 00:43
von BlackJack
@mzh: Ansonsten muss man das ja auch nicht mit aller Gewalt in eine ``lambda``-Funktion quetschen wollen. In einer mit ``def`` definierten Funktion kann man mehr machen, zum Beispiel den Sonderfall mit einem ``if`` behandeln.
Re: Vergleich von zwei Files
Verfasst: Freitag 14. Mai 2010, 02:38
von noisefloor
Hallo,
die potentiellen Leerzeilen war ja auch das, was mich zu meinem Codebewegt hat. Da werden diese nämlich gekonnt ignoriert.

. Na gut, Nachteile -> siehe oben.
Gruß, noisefloor
Re: Vergleich von zwei Files
Verfasst: Freitag 14. Mai 2010, 11:57
von mzh
BlackJack hat geschrieben:@mzh: Ansonsten muss man das ja auch nicht mit aller Gewalt in eine ``lambda``-Funktion quetschen wollen. In einer mit ``def`` definierten Funktion kann man mehr machen, zum Beispiel den Sonderfall mit einem ``if`` behandeln.
Natürlich, da stimme ich voll zu... für mich ist es einfach eine gute Gelegenheit, die verschiedenen Sprachelemente von Python ein bisschen besser kennen zu lernen. Das war die Motivation für mich, das so zu versuchen.
@noisefloor: soweit ich das sehe, löst der Vorschlag von bords0 das Problem mit den Leerzeilen ebenfalls recht einfach