it-swarm.dev

بيثون - الفرق بين سلسلتين

أود تخزين الكثير من الكلمات في قائمة. العديد من هذه الكلمات متشابهة جدا. على سبيل المثال لدي Word afrykanerskojęzyczny والعديد من الكلمات مثل afrykanerskojęzycznym و afrykanerskojęzyczni و nieafrykanerskojęzyczni. ما هو الحل الفعال (بسرعة وإعطاء حجم فرق صغير) لإيجاد الفرق بين سلسلتين واستعادة السلسلة الثانية من الأولى والفرق؟

55
user2626682

يمكنك استخدام ndiff في وحدة difflib للقيام بذلك. لديه كل المعلومات اللازمة لتحويل سلسلة واحدة إلى سلسلة أخرى.

مثال بسيط:

import difflib

cases=[('afrykanerskojęzyczny', 'afrykanerskojęzycznym'),
       ('afrykanerskojęzyczni', 'nieafrykanerskojęzyczni'),
       ('afrykanerskojęzycznym', 'afrykanerskojęzyczny'),
       ('nieafrykanerskojęzyczni', 'afrykanerskojęzyczni'),
       ('nieafrynerskojęzyczni', 'afrykanerskojzyczni'),
       ('abcdefg','xac')] 

for a,b in cases:     
    print('{} => {}'.format(a,b))  
    for i,s in enumerate(difflib.ndiff(a, b)):
        if s[0]==' ': continue
        Elif s[0]=='-':
            print(u'Delete "{}" from position {}'.format(s[-1],i))
        Elif s[0]=='+':
            print(u'Add "{}" to position {}'.format(s[-1],i))    
    print()      

مطبوعات:

afrykanerskojęzyczny => afrykanerskojęzycznym
Add "m" to position 20

afrykanerskojęzyczni => nieafrykanerskojęzyczni
Add "n" to position 0
Add "i" to position 1
Add "e" to position 2

afrykanerskojęzycznym => afrykanerskojęzyczny
Delete "m" from position 20

nieafrykanerskojęzyczni => afrykanerskojęzyczni
Delete "n" from position 0
Delete "i" from position 1
Delete "e" from position 2

nieafrynerskojęzyczni => afrykanerskojzyczni
Delete "n" from position 0
Delete "i" from position 1
Delete "e" from position 2
Add "k" to position 7
Add "a" to position 8
Delete "ę" from position 16

abcdefg => xac
Add "x" to position 0
Delete "b" from position 2
Delete "d" from position 4
Delete "e" from position 5
Delete "f" from position 6
Delete "g" from position 7
72
dawg

تعجبني الإجابة ndiff ، ولكن إذا كنت ترغب في إدخالها في قائمة التغييرات فقط ، فيمكنك فعل شيء مثل:

import difflib

case_a = 'afrykbnerskojęzyczny'
case_b = 'afrykanerskojęzycznym'

output_list = [li for li in difflib.ndiff(case_a, case_b) if li[0] != ' ']
8
Eric

يمكنك أن تبحث في وحدة regex (القسم غامض). لا أعرف ما إذا كان يمكنك الحصول على الاختلافات الفعلية ، ولكن على الأقل يمكنك تحديد عدد المسموح به من أنواع مختلفة من التغييرات مثل الإدراج والحذف والبدائل:

import regex
sequence = 'afrykanerskojezyczny'
queries = [ 'afrykanerskojezycznym', 'afrykanerskojezyczni', 
            'nieafrykanerskojezyczni' ]
for q in queries:
    m = regex.search(r'(%s){e<=2}'%q, sequence)
    print 'match' if m else 'nomatch'
2
perreal

ما تطلبه هو شكل متخصص من الضغط. xdelta3 تم تصميمه لهذا النوع المعين من الضغط ، وهناك ارتباط بيثون له ، لكن من المحتمل أن تفلت من استخدام zlib مباشرة. تريد استخدام zlib.compressobj و zlib.decompressobj مع تعيين المعلمة zdict على "Word الأساسي" ، على سبيل المثال afrykanerskojęzyczny.

التحذيرات هي zdict معتمدة فقط في python 3.3 أو أعلى ، ومن الأسهل الرمز إذا كان لديك "الكلمة الأساسية" نفسها لكل فروقك ، والتي قد تكون أو لا تكون ما تريد.

2
Craig Silverstein