2010-04-27 8 views
7

मैं difflib.Differ के समान तरीके से दो सूचियों को संरेखित करना चाहता हूं, सिवाय इसके कि मैं आइटम की तुलना करने के लिए एक मैच फ़ंक्शन को परिभाषित करने में सक्षम होना चाहता हूं, केवल स्ट्रिंग समानता का उपयोग न करें, और अधिमानतः एक मैच फ़ंक्शन जो एक संख्या वापस कर सकता है 0.0 और 1.0 के बीच, सिर्फ एक बूलियन नहीं।मनमानी मिलान फ़ंक्शन का उपयोग करके पाइथन सूचियों को कैसे अलग/संरेखित करना है?

तो, उदाहरण के लिए, मैं दो सूचियों था:

L1 = [('A', 1), ('B', 3), ('C', 7)] 
L2 = ['A', 'b', 'C'] 

और मैं इस तरह एक मैच समारोह में लिखने के लिए सक्षम होना चाहते हैं:

def match(item1, item2): 
    if item1[0] == item2: 
     return 1.0 
    elif item1[0].lower() == item2.lower(): 
     return 0.5 
    else: 
     return 0.0 

और उसके बाद है:

d = Differ(match_func=match) 
d.compare(L1, L2) 

और यह मैच फ़ंक्शन का उपयोग करके भिन्न है। difflib की तरह, मैं बल्कि एल्गोरिदम ने पूरी तरह से न्यूनतम लेवेनशेटिन दूरी की बजाय अधिक सहज ज्ञान युक्त रत्क्लिफ-ओबर्सहेल्प प्रकार के परिणाम दिए।

+0

यह एक विशेष करने की "लागत" निर्दिष्ट करने के लिए सक्षम किया जा रहा से संबंधित है एल 1 से प्राप्त करने के लिए की जगह एल 2 लेकिन नोटिस प्रत्येक सूची आइटम को एक जटिल संरचना के लिए भी अनुमति देता है, जिसमें से केवल –

+0

तुलना में भूमिका निभा सकता है कि प्राथमिक उद्देश्य यह है कि कौन से आइटम (मोटे तौर पर) मेल खाते हैं और पहचानें कि कौन सी चीजें जोड़ी नहीं हैं ऊपर; इसलिए यह परंपरागत नहीं है "एल 1 से एल 2 तक पहुंचने के लिए कदम" diff –

+0

am क्या मैं मूल रूप से पायथन में सुडलमन-वंसच या स्मिथ-वाटमैन एल्गोरिदम की तरह कुछ ढूंढ रहा हूं? –

उत्तर

8

मैं सिर्फ Needleman-Wunsch के इस कार्यान्वयन लिखा था और यह मैं क्या चाहते हो रहा है:

def nw_align(a, b, replace_func, insert, delete): 

    ZERO, LEFT, UP, DIAGONAL = 0, 1, 2, 3 

    len_a = len(a) 
    len_b = len(b) 

    matrix = [[(0, ZERO) for x in range(len_b + 1)] for y in range(len_a + 1)] 

    for i in range(len_a + 1): 
     matrix[i][0] = (insert * i, UP) 

    for j in range(len_b + 1): 
     matrix[0][j] = (delete * j, LEFT) 

    for i in range(1, len_a + 1): 
     for j in range(1, len_b + 1): 
      replace = replace_func(a[i - 1], b[j - 1]) 
      matrix[i][j] = max([ 
       (matrix[i - 1][j - 1][0] + replace, DIAGONAL), 
       (matrix[i][j - 1][0] + insert, LEFT), 
       (matrix[i - 1][j][0] + delete, UP) 
      ]) 

    i, j = len_a, len_b 
    align_a = "" 
    align_b = "" 

    while (i, j) != (0, 0): 
     if matrix[i][j][1] == DIAGONAL: 
      align_a += a[i - 1] 
      align_b += b[j - 1] 
      i -= 1 
      j -= 1 
     elif matrix[i][j][1] == LEFT: 
      align_a += "-" 
      align_b += b[j - 1] 
      j -= 1 
     else: # UP 
      align_a += a[i - 1] 
      align_b += "-" 
      i -= 1 

    return align_a[::-1], align_b[::-1] 
+0

+1 पर एक स्टैंडअलोन स्क्रिप्ट पर निकाला है, इसकी सराहना की गई है – msw

0

मैंने हाल ही में patience diff नामक एल्गोरिदम की चर्चा में भाग लिया जो अपेक्षाकृत आसान लगता है। आप इसे स्वयं लागू करने का प्रयास कर सकते हैं, और फिर निश्चित रूप से आप इसे जो भी तुलना एल्गोरिदम पसंद करते हैं उसका उपयोग कर सकते हैं।

+0

यदि इसका उपयोग bzr में किया जाता है जिसका अर्थ हो सकता है कि पाइथन कार्यान्वयन पहले से मौजूद है –

+0

हाँ, ऐसा करता है। मैंने स्वयं को फॉलो-अप के लिए http://stackoverflow.com/questions/4599456/textually-diffing-json/4599500#4599500 – TryPyPy

संबंधित मुद्दे