2010-01-08 5 views
2

Selon la documentation, vous pouvez fournir une fonction linejunk pour ignorer les lignes certian. Cependant, je ne peux pas le faire fonctionner. Voici quelques exemples de code pour la discussion:Comment ignorer les lignes en utilisant difflib.ndiff?

from re import search 
from difflib import ndiff 
t1 = 'one 1\ntwo 2\nthree 3' 
t2 = 'one 1\ntwo 29\nthree 3' 
diff = ndiff(t1.splitlines(), t2.splitlines(), lambda x: search('2', x)) 

Mon intention est d'ignorer la deuxième ligne et diff sera un générateur qui ne montre pas de différences.

Merci pour l'aide.

Répondre

0

Votre exemple a un problème: les deux premiers arguments de ndiff doivent être chacun une liste de chaînes; vous avez une seule chaîne qui est traitée comme une liste de caractères. Voir the docs. Utilisez par exemple Toutefois, comme l'exemple suivant le montre, difflib.ndiff n'appelle pas la fonction linejunk pour toutes les lignes. C'est un comportement de longue date - vérifié avec Python 2.2 à 2.6 inclusivement, et 3.1.

script Exemple:

from difflib import ndiff 
t1 = 'one 1\ntwo 2\nthree 3'.splitlines() 
t2 = 'one 1\ntwo 29\nthree 3'.splitlines() 
def lj(line): 
    rval = '2' in line 
    print("lj: line=%r, rval=%s" % (line, rval)) 
    return rval 
d = list(ndiff(t1, t2 )); print("%d %r\n" % (1, d)) 
d = list(ndiff(t1, t2, lj)); print("%d %r\n" % (2, d)) 
d = list(ndiff(t2, t1, lj)); print("%d %r\n" % (3, d)) 

sortie de l'exécution avec Python 2.6:

1 [' one 1', '- two 2', '+ two 29', '?  +\n', ' three 3'] 

lj: line='one 1', rval=False 
lj: line='two 29', rval=True 
lj: line='three 3', rval=False 
2 [' one 1', '- two 2', '+ two 29', '?  +\n', ' three 3'] 

lj: line='one 1', rval=False 
lj: line='two 2', rval=True 
lj: line='three 3', rval=False 
3 [' one 1', '- two 29', '?  -\n', '+ two 2', ' three 3'] 

Vous pouvez signaler cela comme un bug. Notez cependant que les docs ne disent pas explicitement quelle signification est attachée aux lignes qui sont "junk". Quel résultat attendiez-vous?

De plus perplexes: l'ajout de ces lignes au script:

t3 = 'one 1\n \ntwo 2\n'.splitlines() 
t4 = 'one 1\n\n#\n\ntwo 2\n'.splitlines() 
d = list(ndiff(t3, t4  )); print("%d %r\n" % (4, d)) 
d = list(ndiff(t4, t3  )); print("%d %r\n" % (5, d)) 
d = list(ndiff(t3, t4, None)); print("%d %r\n" % (6, d)) 
d = list(ndiff(t4, t3, None)); print("%d %r\n" % (7, d)) 

produit cette sortie:

4 [' one 1', '- ', '+ ', '+ #', '+ ', ' two 2'] 

5 [' one 1', '+ ', '- ', '- #', '- ', ' two 2'] 

6 [' one 1', '- ', '+ ', '+ #', '+ ', ' two 2'] 

7 [' one 1', '+ ', '- ', '- #', '- ', ' two 2'] 

En d'autres termes, le résultat lorsque vous utilisez la fonction linejunk par défaut est le même que celui de ne pas utiliser un fonction linejunk, dans un cas contenant différentes lignes "junk" (espace blanc sauf un hash initial). Peut-être que si vous pouviez nous dire ce que vous essayez d'atteindre, nous pourrions peut-être vous proposer une autre approche.

Modifier après plus d'info

Si votre intention est en généralité d'ignorer toutes les lignes contenant « 2 », ce qui signifie prétendre qu'ils n'existent pas à des fins Ndiff, tout ce que vous devez faire est de tourner le prétexte en réalité:

t1f = [line for line in t1 if '2' not in line] 
t2f = [line for line in t2 if '2' not in line] 
diff = ndiff(t1f, t2f) 
+0

Mon intention est d'ignorer la deuxième ligne et diff sera un générateur qui ne montre aucune différence. – behindalens

+0

J'ai fini par faire ça. À l'origine, j'utilisais la fonction HtmlDiff et je voulais ignorer (plutôt que supprimer) certaines lignes lors de la création de la sortie html. J'ai été conduit à ndiff depuis la documentation a laissé entendre que les deux étaient liés. Je me demande ce que fait réellement la fonction linejunk à ce stade. – behindalens

+0

@behindalens: Je partage votre merveille. Je peux soumettre un rapport de bogue et/ou une demande de clarification de documents. Je peux même lire le code source :-) ... en attendant, considérez-vous que votre question a été répondue? –

3

J'ai récemment rencontré le même problème. Voici ce que j'ai découvert:

cf. http://bugs.python.org/issue14332

Le but principal des * paramètres indésirables est d'accélérer correspondant à trouver des différences, ne pas masquer les différences.

c.f. http://hg.python.org/cpython/rev/0a69b1e8b7fe/

Le patch fournit une meilleure explication de la « junk » et « ignorer » les concepts dans difflib docs

Ces fonctions junk-filtrage accélèrent correspondant à trouver des différences et ne causent pas de lignes différentes ou des caractères à ignorer.

+0

Ceci devrait être la réponse acceptée à cette question. – matthewatabet

Questions connexes