2009-03-31 10 views
5

कहें कि मेरे पास शब्दों की एक स्ट्रिंग है: 'a b c d e f'। मैं इस स्ट्रिंग से बहु-शब्द शर्तों की एक सूची उत्पन्न करना चाहता हूं।मैं बहु शब्द शब्दों को बार-बार कैसे उत्पन्न करूं?

शब्द आदेश महत्वपूर्ण है। उपरोक्त उदाहरण से 'f e d' शब्द उत्पन्न नहीं किया जाना चाहिए।

संपादित करें: इसके अलावा, शब्दों को छोड़ना नहीं चाहिए। 'a c', या 'b d f' उत्पन्न नहीं किया जाना चाहिए।

क्या मैं अभी:

doc = 'a b c d e f' 
terms= [] 
one_before = None 
two_before = None 
for word in doc.split(None): 
    terms.append(word) 
    if one_before: 
     terms.append(' '.join([one_before, word])) 
    if two_before: 
     terms.append(' '.join([two_before, one_before, word])) 
    two_before = one_before 
    one_before = word 

for term in terms: 
    print term 

प्रिंटों:

a 
b 
a b 
c 
b c 
a b c 
d 
c d 
b c d 
e 
d e 
c d e 
f 
e f 
d e f 

मैं इस एक पुनरावर्ती समारोह कैसे कर सकता हूँ ताकि मैं इसे शब्दों का एक चर अधिकतम संख्या पारित कर सकते हैं होगा प्रति शब्द?

आवेदन:

मैं HTML दस्तावेज़ में पठनीय पाठ से बहु-शब्द संदर्भ उत्पन्न करने के लिए इस का उपयोग किया जाएगा। समग्र लक्ष्य एक बड़े कॉर्पस (लगभग दो मिलियन दस्तावेज) का एक गुप्त अर्थपूर्ण विश्लेषण है। यही कारण है कि शब्द आदेश मामलों को ध्यान में रखते हुए (प्राकृतिक भाषा प्रसंस्करण और क्या नहीं)।

+0

सादगी के लिए मैंने शब्दों के लिए एकल अक्षरों को प्रतिस्थापित किया। – tgray

+0

क्या आपका मतलब "प्रति शब्द शब्दों की अधिकतम संख्या" है? क्योंकि यह वर्तमान रूप में मुझे समझ में नहीं आता है। – SilentGhost

+0

मुझे लगता है कि असली सवाल यह है कि क्या नौकरी करने के लिए इसे रिकर्सिव करने की आवश्यकता है? क्या यहां रिकर्सन की आवश्यकता है? –

उत्तर

11

यह रिकर्सिव नहीं है, लेकिन मुझे लगता है कि यह वही करता है जो आप चाहते हैं।

def find_terms(words, max_words_per_term):  
    if len(words) == 0: return [] 
    return [" ".join(words[:i+1]) for i in xrange(min(len(words), max_words_per_term))] + find_terms(words[1:], max_words_per_term) 


doc = 'a b c d e f' 
words = doc.split(None) 
for term in find_terms(words, 3): 
    print term 

यहाँ, फिर से पुनरावर्ती क्रिया है कुछ समझा चर और टिप्पणियों के साथ:

doc = 'a b c d e f' 
words = doc.split(None) 
max = 3   


for index in xrange(len(words)):  
    for n in xrange(max): 
     if index + n < len(words):   
      print ' '.join(words[index:index+n+1]) 

और यहाँ एक पुनरावर्ती समाधान है।

def find_terms(words, max_words_per_term): 

    # If there are no words, you've reached the end. Stop.  
    if len(words) == 0: 
     return []  

    # What's the max term length you could generate from the remaining 
    # words? It's the lesser of max_words_per_term and how many words 
    # you have left.               
    max_term_len = min(len(words), max_words_per_term)  

    # Find all the terms that start with the first word. 
    initial_terms = [" ".join(words[:i+1]) for i in xrange(max_term_len)] 

    # Here's the recursion. Find all of the terms in the list 
    # of all but the first word. 
    other_terms = find_terms(words[1:], max_words_per_term) 

    # Now put the two lists of terms together to get the answer. 
    return initial_terms + other_terms 
+0

ऐसा लगता है कि मुझे आपके द्वारा प्रदान किए गए पहले समाधान का उपयोग करना होगा। पायथन एक समारोह को 999 गुना से अधिक बार नहीं जाने देगा। मेरे टेस्ट दस्तावेज़ में लगभग 1750 शब्द थे और यह छोटी तरफ है। – tgray

+0

यह समझ में आता है। रिकर्सिव समाधान काम करने के लिए मजेदार था, लेकिन वास्तव में व्यावहारिक नहीं। –

+0

यदि आप वास्तव में गहरी रिकर्सन चाहते हैं, तो आप sys.setrecursionlimit के साथ रिकर्सन सीमा बढ़ा सकते हैं। लेकिन वैसे भी पुनरावृत्ति समाधान शायद बेहतर है। – Kiv

3

मैं सुझाव दूंगा कि आपको अपना कार्य जनरेटर बनाना चाहिए और फिर आवश्यक संख्याएं उत्पन्न करनी चाहिए। आपको print को yield में बदलना होगा (और स्पष्ट रूप से संपूर्ण ब्लॉक फ़ंक्शन बनाना होगा)।

आप itertools मॉड्यूल पर भी देख सकते हैं, यह आपके काम के लिए काफी उपयोगी है।

3

आप ऐसा क्यों कर रहे हैं? आप इसके बजाय बस लूप और itertools.combinations() का उपयोग कर सकते हैं।

+0

अच्छा सुझाव, लेकिन मुझे संरक्षित होने के आदेश की आवश्यकता है। उदाहरण: 'ए बी सी' बनाता है ['ए', 'बी', 'ए बी', 'सी', 'बी सी', 'ए बी सी'], लेकिन 'बी ए' या 'सी बी ए' नहीं। – tgray

+0

यह आदेश को संरक्षित करता है। –

+0

भ्रम के लिए खेद है, यह भी शब्दों को छोड़ना नहीं चाहिए। डॉक्टर "बाड़ पर कूदने वाला त्वरित ब्राउन लोमड़ी" शब्द के रूप में "ब्राउन बाड़" नहीं होना चाहिए। ऐसा करने के लिए itertools का उपयोग करने का कोई तरीका है? – tgray

1

जो आप खोज रहे हैं वह एन-ग्राम एल्गोरिदम है। वह आपको [ए, एबी, बी, बीसी, सी, सीडी, ...] देगा।

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