2016-02-07 6 views
32

मैं स्ट्रिंग में वर्णों से एक सूची बनाना चाहता हूं, लेकिन विशिष्ट कीवर्ड को एक साथ रखना चाहता हूं।क्या आप एक स्ट्रिंग से पाइथन सूची बना सकते हैं, जबकि विशिष्ट कीवर्ड में अक्षरों को एक साथ रखते हुए?

उदाहरण के लिए:

कीवर्ड: कार, बस

इनपुट:

"xyzcarbusabccar" 

उत्पादन:

["x", "y", "z", "car", "bus", "a", "b", "c", "car"] 

उत्तर

38

re.findall के साथ। पहले अपने खोजशब्दों के बीच वैकल्पिक।

>>> import re 
>>> s = "xyzcarbusabccar" 
>>> re.findall('car|bus|[a-z]', s) 
['x', 'y', 'z', 'car', 'bus', 'a', 'b', 'c', 'car'] 

मामले में आप अतिव्यापी कीवर्ड हैं, तो ध्यान दें कि यह समाधान पहले एक आपके सामने आ पाएंगे:

>>> s = 'abcaratab' 
>>> re.findall('car|rat|[a-z]', s) 
['a', 'b', 'car', 'a', 't', 'a', 'b'] 

आप [a-z] हिस्सा जो कुछ के साथ आप की तरह प्रतिस्थापन समाधान अधिक सामान्य बना सकते हैं, उदाहरण के लिए \w, या किसी भी चरित्र से मेल खाने के लिए एक साधारण .

लघु स्पष्टीकरण क्यों यह काम करता है और यही कारण है कि regex '[a-z]|car|bus' काम नहीं होगा: नियमित अभिव्यक्ति इंजन बाएं से दाएं बारी विकल्पों की कोशिश करता है और "उत्सुक" एक मैच वापस जाने के लिए है। इसका अर्थ यह है कि जैसे ही विकल्पों में से एक पूरी तरह मेल खाया गया है, यह पूरी तरह मिलान करने के लिए पूरे विकल्प को मानता है। इस बिंदु पर, यह शेष विकल्पों में से किसी एक को आजमाएगा लेकिन तुरंत एक मैच को प्रोसेसिंग और रिपोर्ट करना बंद कर देगा। '[a-z]|car|bus' के साथ, इंजन एक वर्ण की रिपोर्ट करेगा जब यह चरित्र वर्ग [ए-जेड] में किसी भी चरित्र को देखता है और यह जांचने के लिए कभी नहीं चलता कि 'कार' या 'बस' का मिलान भी किया जा सकता है या नहीं।

+0

महान समाधान की तरह दिखता है। '' [A-z] | 'का उपयोग करना + '|'। जॉइन (कीवर्ड) 'प्रोग्रामेटिक रूप से रेगेक्स बनाने में आसान बना देगा। – SuperBiasedMan

+2

@SuperBiasedMan धन्यवाद। यह '' | '.join (कीवर्ड) +' | [ए-जेड] '' हालांकि, ऑर्डर महत्वपूर्ण है क्योंकि रेगेक्स इंजन बाएं से दाएं विकल्प को कोशिश करता है और एक मैच वापस करने के लिए * उत्सुक * है। यही कारण है कि समाधान काम करता है, शायद मुझे एक स्पष्टीकरण में संपादित करना चाहिए। – timgeb

+0

आह, मूर्ख मुझे! मैं ज्यादा रेगेक्स का उपयोग नहीं करता, और मैंने सोचा कि दूसरा ऑर्डर अधिक पठनीय होगा। – SuperBiasedMan

16
s = "xyzcarbusabccar" 
import re 

print re.findall("bus|car|\w", s) 
['x', 'y', 'z', 'car', 'bus', 'a', 'b', 'c', 'car'] 

या हो सकता है \S किसी भी गैर खाली स्थान के वर्ण के लिए:

s = "xyzcarbusabccar!" 
import re 

print re.findall("bus|car|\S", s) 
['x', 'y', 'z', 'car', 'bus', 'a', 'b', 'c', 'car', '!'] 

बस सुनिश्चित करें कि आप सही क्रम लंबे समय तक शब्द पहले डाल पाने के लिए यदि आप लंबे समय तक मैचों चाहते हैं।

In [7]: s = "xyzcarsbusabccar!" 

In [8]: re.findall("bus|car|cars|\S", s) 
Out[8]: ['x', 'y', 'z', 'car', 's', 'bus', 'a', 'b', 'c', 'car', '!'] 

In [9]: re.findall("bus|cars|car|\S", s) 
Out[9]: ['x', 'y', 'z', 'cars', 'bus', 'a', 'b', 'c', 'car', '!'] 
0

उपर्युक्त समाधान वास्तव में बहुत अच्छे हैं, लेकिन यदि कीवर्ड शब्दकोश लंबा है तो यह आसानी से गन्दा हो सकता है (शायद अनुपूरक)।

मैं एक पेड़ में कीवर्ड को स्टोर करने का प्रस्ताव करता हूं (जो अनावश्यकता का फायदा उठाता है) और अधिक अंतरिक्ष कुशल है।

कीवर्ड ["art,"at","atm","bus","can","car"] हैं की तरह इस

    . 
       ^
      / ¦  \ 

     / ¦  \ 
     a  b   c 
     ^ ^  ^
    / \  \   \ 
    r  t  u   a 
    ^ ^ ^  ^
/ /\  \  / \ 
    t  m /0  s  n  r 
^ ^  ^ ^ ^
/ /   \  \  \ 
/0  /0    /0  /0 /0 

मैं इसे द्विआधारी के बाद से यह आकर्षित करने के लिए आसान था बनाया शब्दकोश लग रहा है। नोड "/0" में शब्द अंत (आभासी चरित्र) का महत्व है और "." रूट है।

मैं पेड़ और आवश्यक कार्यों

class Tree(object): 

    def __init__(self, name='root', children=None): 
     self.name = name 
     self.children = {} 
     if children is not None: 
      for child in children: 
       self.add_child(child.name,child) 

    def __repr__(self): 
     return self.name 

    def add_child(self, node): 
     assert isinstance(node, Tree) 
     self.children[node.name] = node 


    def has_child(self,name): 
     return name in self.children 

    def get_child(self,name): 
     return self.children[name] 

    def print_tree(self,level=0): 
     sys.stdout.write('-' * level) 
     print self.name 
     for childTag in self.children: 
      self.children[childTag].print_tree(level+1) 

निर्माण करने के लिए कीवर्ड हम इस

keywords = ["car","at","atm","bus"] 
keywordsTree = Tree('') 

for keyword in keywords: 
    keywordsTreeNode = keywordsTree 
    for character in keyword: 
     if not keywordsTreeNode.has_child(character): 
      keywordsTreeNode.add_child(Tree(character)) 
     keywordsTreeNode = keywordsTreeNode.get_child(character) 

    keywordsTreeNode.add_child(Tree('/0')) 

की तरह कोड का उपयोग कर संरचना का निर्माण कर सकते देखते हुए इस सरल ट्री वर्ग कार्यान्वित अंत में हम कीवर्ड के लिए इनपुट खोज । नीचे दिया गया समाधान उस स्थिति से शुरू होने वाले सभी कीवर्ड इनपुट में दी गई स्थिति के लिए प्रदान करता है।

inputWords = "xyzcarbusabccar8hj/0atm" 
output = [] 
lengthInput = len(inputWords) 
for position in range(0,lengthInput): 
    ##add by default the character 
    # allMathcedKeyWords = [inputWords[position]] 

    allMathcedKeyWords = [] 
    keywordsTreeNode = keywordsTree 
    searchPosition = position 
    curMathcedWord = '' 

    while searchPosition < lengthInput and keywordsTreeNode.has_child(inputWords[searchPosition]) : 

     keywordsTreeNode = keywordsTreeNode.get_child(inputWords[searchPosition]) 
     curMathcedWord = curMathcedWord + inputWords[searchPosition] 

     if (keywordsTreeNode.has_child("/0")): 
      allMathcedKeyWords.append(curMathcedWord) 

     searchPosition += 1 

    if len(allMathcedKeyWords)==0: 
     allMathcedKeyWords = inputWords[position] 

    output.append(allMathcedKeyWords) 

print output 

इस कोड को आउटपुट इस

['x', 'y', 'z', 
['car'], 
'a', 'r', 
['bus'], 
    'u', 's', 'a', 'b', 'c', 
['car'], 
    'a', 'r', '8', 'h', 'j', '/', '0', 
['at', 'atm'], 
    't', 'm'] 

ऊपर कोड के लिए महत्वपूर्ण तथ्य यह है कि शब्द के अंत में आभासी चरित्र दो पत्र ("/0") और मिलान किया जा कभी नहीं होगा (भले ही जैसा कि ऊपर वर्णित इनपुट अनुक्रम में संयोजन प्रकट होता है)। इसके अलावा यह किसी भी स्ट्रिंग कैरेक्टर को नियंत्रित करता है (इनपुट और कीवर्ड के लिए - re.findall() में से बचने वाले वर्णों को भी पेश करने की आवश्यकता नहीं है)

इस आउटपुट सूची से आप यह तय कर सकते हैं कि आप क्या करना चाहते हैं। यदि आप चाहते हैं कि re.findall का समाधान किसी स्थिति के लिए सबसे लंबा मिलान वाला शब्द ढूंढें (या कीवर्ड लॉजिकल ऑर्डर के आधार पर) और शब्द वाले वर्णों की संख्या आगे बढ़ें।

समस्या को और भी आगे लेना, इनपुट में प्रत्येक वर्ण एक कशेरुक है और जब आप किसी शब्द को मिलान किए गए शब्द के अंतिम चरित्र के बाद उस स्थिति से संबंधित अगली कशेरुक में किनारे जोड़ते हैं। एक सबसे छोटा रास्ता एल्गोरिदम आपको फिर से समाधान प्रदान करेगा। इस तरह के आउटपुट का निर्माण करने से अंतरिक्ष दक्षता फिर से आती है और अधिक जटिल एल्गोरिदम के लिए दरवाजा खुलता है।

उदाहरण के लिए, हो रही कीवर्ड "car" और "art" और कला और इनपुट अनुक्रम "acart" जिसके परिणामस्वरूप रेखांकन इस

   ______________ 
      ¦    ¦ 
- a -> c -> a -> r -> t -> 
     ¦______________¦ 

जटिलता विश्लेषण

Space : longest_word_length * number_of_letters_in_keywords 
     input_length + input_length * input_length (worst case-fully connected graph) 
Time : input_length * longest_word_length 
     input_length + input_length * input_length (worst case-fully connected graph) 
संबंधित मुद्दे

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