अजगर - दो तारों के बीच का अंतर


87

मैं एक सूची में बहुत सारे शब्द संग्रह करना चाहूंगा। इनमें से कई शब्द बहुत समान हैं। उदाहरण के लिए मैं शब्द है afrykanerskojęzycznyऔर जैसे शब्दों के कई afrykanerskojęzycznym, afrykanerskojęzyczni, nieafrykanerskojęzyczni। दो तारों के बीच अंतर खोजने और पहले एक से दूसरी स्ट्रिंग को पुनर्स्थापित करने और अलग करने के लिए प्रभावी (तेज और छोटा आकार देने वाला) समाधान क्या है?


1
"पहले से दूसरे स्ट्रिंग को पुनर्स्थापित करें और अलग करें" से
jrd1

2
मेरा मानना ​​है कि उनका मतलब है "पहले की तरह दूसरा तार बनाओ"।
एलियास बेनेवेदेस

1
@ एलियासबेवेदेस, बिल्कुल :)।
user2626682

1
क्या आप कुछ पसंद कर रहे हैं difflib? यदि ऐसा है, तो देखें, जैसे, stackoverflow.com/questions/774316/…
torek

जवाबों:


109

ऐसा करने के लिए आप difflib मॉड्यूल में ndiff का उपयोग कर सकते हैं । इसमें एक स्ट्रिंग को दूसरे स्ट्रिंग में बदलने के लिए आवश्यक सभी जानकारी है।

एक सरल उदाहरण:

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

14
+1 पायथन में बहुत सारे उपयोगी मॉड्यूल हैं। ऐसा लगता है कि मैं हर दिन एक नए के बारे में सीखता हूं।
अरशजी

1
यह मैन्युअल रूप से अंतर के माध्यम से आगे बढ़ रहा है; दो तारों के बीच के अंतर को अलग करना, निश्चित रूप से डिफ्लिब.रिस्टोर के
dawg

धन्यवाद! लेकिन मुझे यकीन नहीं है कि यह स्मृति कुशल है। सूची (difflib.ndiff ("afrykanerskojyczyczny", "nieafrykanerskojkanzyczny")) ['+ n', '+ i', '+ e', 'a', 'f', 'y', 'y', 'k' 'k' , 'a', 'n', 'e', ​​'r', 'k', 'k', 'o', 'j', 'ę', 'z', 'y', 'c', '' z ',' n ',' y ']
user2626682

ndiffएक जनरेटर है, इसलिए यह काफी मेमोरी कुशल है। आप listउस पर कॉल कर रहे हैं जो व्यक्तिगत रूप से उत्पन्न वर्ण तुलना को उनकी पूरी सूची में बदल देता है। यदि आप listउस पर कॉल नहीं करते तो आपके पास एक समय में केवल कुछ ही मेमोरी होगी ।
dawg

1
पाइथन 2 पर भी काम करता है (मेरे लिए) मैं विशिष्ट स्रोत और विशिष्ट आउटपुट के साथ एक प्रश्न पूछने का सुझाव दूंगा। मैं टिप्पणी में डिबग नहीं कर सकते हैं ...
dawg

24

मुझे 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] != ' ']

3
यह वही है जो मैं के लिए Googling था। एक त्वरित नोट, @ ईरिक, आपके चर आज के दिखाए गए अनुसार मेल नहीं खाते, 20180905. या तो 1) अंतिम पंक्ति को output_list = [li for li in list(difflib.ndiff(case_a,case_b)) if li[0] != ' ']2 या 2 में बदलें) स्ट्रिंग चर के नामों को case_a -> aऔर के रूप में बदलें case_b -> b। चीयर्स!
bballdave025

3
यह आपकी कमांड के आउटपुट को दिखाने के लिए भी सहायक हो सकता है >>> output_list:; # परिणाम #['- b', '+ a', '+ m']
bballdave025

2
if not li.startswith(' ')कुछ के eqivalent if li[0] != ' 'यह अधिक सुपाठ्य लग सकता है। या यहां तक ​​किif item.startswith(('-', '+', ))
dmmfll

@DMfll डाउनवोट। सूची startswith()में अजगर के रूप में नहीं है3.7.4
नाथन

3

आप रेगेक्स मॉड्यूल (फजी अनुभाग) में देख सकते हैं। मुझे नहीं पता कि क्या आप वास्तविक अंतर प्राप्त कर सकते हैं, लेकिन कम से कम आप विभिन्न प्रकार के परिवर्तनों जैसे डालने, हटाने और प्रतिस्थापन की अनुमत संख्या निर्दिष्ट कर सकते हैं:

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'

3

आप जो पूछ रहे हैं वह संपीड़न का एक विशेष रूप है। xdelta3 को इस विशेष प्रकार के संपीड़न के लिए डिज़ाइन किया गया था, और इसके लिए एक अजगर बंधन है, लेकिन आप सीधे zlib का उपयोग करके दूर हो सकते हैं। आप का उपयोग करना चाहें zlib.compressobjऔर zlib.decompressobjसाथ zdictअपने "आधार शब्द", जैसे करने के लिए पैरामीटर सेट afrykanerskojęzyczny

कैविट्स zdictकेवल पायथन 3.3 और उच्चतर में समर्थित हैं, और यह कोड करना सबसे आसान है यदि आपके पास अपने सभी रूपों के लिए समान "आधार शब्द" है, जो आप चाहते हैं या नहीं हो सकता है।


-2

मूल प्रश्न के ऊपर मेरी टिप्पणी का जवाब मुझे लगता है कि यह वही है जो वह चाहता है:

loopnum = 0
word = 'afrykanerskojęzyczny'
wordlist = ['afrykanerskojęzycznym','afrykanerskojęzyczni','nieafrykanerskojęzyczni']
for i in wordlist:
    wordlist[loopnum] = word
    loopnum += 1

यह निम्न कार्य करेगा:

वर्डलिस्ट में प्रत्येक मान के लिए, वर्डलिस्ट के उस मूल्य को मूल कोड पर सेट करें।

आपको बस इतना करना है कि इस कोड को डाल दिया जाए जहां आपको वर्डलिस्ट बदलने की जरूरत है, यह सुनिश्चित करते हुए कि आप उन शब्दों को स्टोर करें जिन्हें आपको वर्डलिस्ट में बदलने की जरूरत है, और यह कि मूल शब्द सही है।

उम्मीद है की यह मदद करेगा!


धन्यवाद, लेकिन वास्तव में मैं 'nieafrykanerskojyczyczni' जैसे शब्दों को मेमोरी एफिशिएंसी तरीके से स्टोर करना चाहूंगा, 'afrykanerskojęzyczny' की समानता।
user2626682
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.