[Python-de] difflib problem

Berthold Höllmann bhoel at despammed.com
Fr Nov 2 21:25:56 CET 2012


Berthold Hoellmann <berthold at despammed.com> writes:

> Moin,
>
> Ich versuche eine spezielles diff zu schreiben und wollte dazu die
> python difflib nutzen. Allerdings macht sie (natürlich?) nicht das, was
> ich von ihr erwarte;
>
> Python 2.7.3 (default, Jul 24 2012, 15:00:49) 
> [GCC 3.3.3 (SuSE Linux)] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> import difflib
>>>> class line(object):
> ...     def __init__(self, val):
> ...         self.val = val
> ...     def __eq__(self, other):
> ...         print '__eq__', self.val, other.val
> ...         return abs(self.val - other.val) < 1.
> ... 
>>>> f1 = [line(i) for i in [1., 2., 3., 4.]]
>>>> f2 = [line(i) for i in [1.1, 3.1, 3.3, 4.4]]
>>>> 
>>>> match = difflib.SequenceMatcher(None, f1, f2)
>>>> for opcode in match.get_opcodes():
> ...     print "%-7s a[%d:%d] b[%d:%d]" % opcode
> ... 
> __eq__ 1.0 1.1
> __eq__ 2.0 3.1
> __eq__ 2.0 3.1
> equal   a[0:1] b[0:1]
> replace a[1:4] b[1:4]
>>>> 
>
>
> ich hätte deutlich mehr Aufrufe von '__eq__' erwartet und dass Ergebnis:
>
> equal   a[0:1] b[0:1]
> replace a[1:2] b[1:2]
> equal   a[2:4] b[2:4]
>
> Warum gibts das nicht?
>
> Danke
> Berthold

Ich habe dann doch noch eine Lösung gefunden. Wenn ich __hash__ auf eine
ganz böse, verbotene Art und Weise definiere, dann funktionert es wie
ich es mir vorstelle:

In [1]: import difflib

In [2]: def GCount():
   ...:     _val = 0
   ...:     while True:
   ...:         yield _val
   ...:         _val += 1
   ...: 

In [3]: class line(object):
   ...:     def __init__(self, val):
   ...:         self.val = val
   ...:         self._cnt = GCount()
   ...:     def __eq__(self, other):
   ...:         return abs(self.val - other.val) < 1.
   ...:     def __hash__(self):
   ...:         return self._cnt.next()
   ...: 

In [4]: def docmp(a, b):
   ...:     match = difflib.SequenceMatcher(None, a, b)
   ...:     for opcode in match.get_opcodes():
   ...:         print "%-7s a[%d:%d] b[%d:%d]" % opcode
   ...: 

In [5]: docmp([line(i) for i in [1., 2., 3., 4.]],
   ...:       [line(i) for i in [1.1, 3.1, 3.3, 4.4]])
equal   a[0:1] b[0:1]
replace a[1:2] b[1:2]
equal   a[2:4] b[2:4]

In [6]: docmp([line(i) for i in [1., 2., 3., 4.]],
   ...:       [line(i) for i in [1.1, 4, 3.1, 3.3, 4.4]])
equal   a[0:1] b[0:1]
replace a[1:2] b[1:3]
equal   a[2:4] b[3:5]

In [7]: 



-- 
A: Weil es die Lesbarkeit des Textes verschlechtert.
F: Warum ist TOFU so schlimm?
A: TOFU
F: Was ist das größte Ärgernis im Usenet?
-------------- nächster Teil --------------
Ein Dateianhang mit Binärdaten wurde abgetrennt...
Dateiname   : nicht verfügbar
Dateityp    : application/pgp-signature
Dateigröße  : 197 bytes
Beschreibung: nicht verfügbar
URL         : <http://mail.python.org/pipermail/python-de/attachments/20121102/b666ae1d/attachment.pgp>


Mehr Informationen über die Mailingliste python-de