2015-12-22 8 views
7

मैं ऐसे जैसे तार की एक सूची है की एक निश्चित सेट के आधार पर,विभाजन एक स्ट्रिंग शब्द

['happy_feet', 'happy_hats_for_cats', 'sad_fox_or_mad_banana','sad_pandas_and_happy_cats_for_people'] 

एक कीवर्ड सूची ['for', 'or', 'and'] जैसे मैं एक और सूची में सूची पार्स जहां अगर करने के लिए सक्षम होना चाहते हैं को देखते हुए कीवर्ड सूची स्ट्रिंग में होती है, उस स्ट्रिंग को कई हिस्सों में विभाजित करें।

उदाहरण के लिए, ऊपर सेट

['happy_feet', 'happy_hats', 'cats', 'sad_fox', 'mad_banana', 'sad_pandas', 'happy_cats', 'people'] 

भागों में विभाजित किया वर्तमान में मैं अंडरस्कोर द्वारा प्रत्येक भीतरी स्ट्रिंग विभाजित है और एक कुंजी शब्द के एक सूचकांक के लिए देख रहा है, तो द्वारा तार के पुनर्संयोजन के पाश के लिए एक है किया है को रेखांकित। क्या ऐसा करने का कोई तेज तरीका है?

+1

यह वास्तव में शायद तेज़ है। क्या यह आपके आवेदन के लिए बहुत धीमा है? – TigerhawkT3

+0

वास्तव में, मैं पाइथन के लिए बिल्कुल नया नहीं हूं और यह नहीं जानता था कि ऐसा करने का एक बेहतर, अधिक संक्षिप्त तरीका है या नहीं। – SharpObject

+1

मैं आमतौर पर अनुकूलन से पहले मापने की सलाह देते हैं। :) विशेष रूप से बुनियादी स्ट्रिंग ऑपरेशंस अक्सर अधिक जटिल दृष्टिकोण से तेज़ होते हैं, वैसे भी। – TigerhawkT3

उत्तर

6
>>> pat = re.compile("_(?:%s)_"%"|".join(sorted(split_list,key=len))) 
>>> list(itertools.chain(pat.split(line) for line in data)) 

आपके द्वारा दी गई उदाहरण डाटासेट

_ सीमांकक आप न साथ

वास्तव में के लिए वांछित आउटपुट दे देंगे वास्तव में इसे लंबाई से क्रमबद्ध करने की आवश्यकता है ताकि आप

>>> pat = re.compile("_(?:%s)_"%"|".join(split_list)) 
>>> list(itertools.chain(pat.split(line) for line in data)) 
कर सकें

from itertools import chain 
import re 

pattern = re.compile(r'_(?:{})_'.format('|'.join([re.escape(w) for w in keywords]))) 

result = list(chain.from_iterable(pattern.split(w) for w in input_list)) 

पैटर्न गतिशील कीवर्ड की अपनी सूची से बनाई गई है:

6
>>> [re.split(r"_(?:f?or|and)_", s) for s in l] 
[['happy_feet'], 
['happy_hats', 'cats'], 
['sad_fox', 'mad_banana'], 
['sad_pandas', 'happy_cats', 'people']] 

उन्हें एक ही सूची में गठबंधन के लिए, आप उपयोग कर सकते हैं

result = [] 
for s in l: 
    result.extend(re.split(r"_(?:f?or|and)_", s)) 
+0

शब्दों के किसी भी सेट को संभालने के लिए इसे एक अतिरिक्त कदम की आवश्यकता है, और यह शब्द काम नहीं करेगा अगर शब्द शुरुआत में या स्ट्रिंग के अंत में है। – Holt

+0

जो ओपी द्वारा उल्लिखित आवश्यकताओं में नहीं था (इसलिए मेरे समान उत्तर पर अस्वीकरण) ... –

+0

@Holt: दाएं, जोरन का संस्करण पहले संबंध में बेहतर है। सुनिश्चित नहीं है कि दूसरा एक समस्या है या नहीं। –

6

आप रेगुलर एक्सप्रेशन का उपयोग कर सकते हैं। स्ट्रिंग 'happy_hats_for_cats''_for_' पर विभाजित है:

>>> re.split(r'_(?:for|or|and)_', 'sad_pandas_and_happy_cats_for_people') 
['sad_pandas', 'happy_cats', 'people'] 

प्रत्येक विभाजन परिणाम:

>>> re.split(r'_for_', 'happy_hats_for_cats') 
['happy_hats', 'cats'] 

लेकिन क्योंकि हम वास्तव में विकल्प का एक सेट (| metacharacter उपयोग करते हुए) आप खोजशब्दों में से किसी पर विभाजित करने के लिए मिल का उत्पादन आपको तारों की एक सूची देता है (केवल एक अगर विभाजित करने के लिए कुछ भी नहीं था); itertools.chain.from_iterable() का उपयोग करके हम उन सभी सूचियों को एक लंबे समय तक टिकाऊ मानते हैं।

डेमो:

>>> from itertools import chain 
>>> import re 
>>> keywords = ['for', 'or', 'and'] 
>>> input_list = ['happy_feet', 'happy_hats_for_cats', 'sad_fox_or_mad_banana','sad_pandas_and_happy_cats_for_people'] 
>>> pattern = re.compile(r'_(?:{})_'.format('|'.join([re.escape(w) for w in keywords])))  
>>> list(chain.from_iterable(pattern.split(w) for w in input_list)) 
['happy_feet', 'happy_hats', 'cats', 'sad_fox', 'mad_banana', 'sad_pandas', 'happy_cats', 'people'] 
+0

महान दिमाग और यह सब: पी –

+1

@ जोरन बेस्ले: यह इस समय एक क्रैपी मोबाइल नेटवर्क पर है :-(मेरी ट्रेन यात्रा के पहले 20 मिनट के लिए ज्यादा कनेक्टिविटी नहीं है (यह आता है और जाता है)। –

2

यह कर, केवल अंतर्निहित विधि का उपयोग का एक और तरीका है, क्या एक स्थानापन्न के तार के साथ हर स्ट्रिंग में ['for', 'or', 'and'] में है के सभी घटना को बदलने के लिए है, उदाहरण के _1_ के लिए कहते हैं (यह हो सकता कोई भी स्ट्रिंग हो), तो फिर, प्रत्येक यात्रा के अंत इस प्रतिस्थापन स्ट्रिंग में विभाजित करने के लिए है:

l = ['happy_feet', 'happy_hats_for_cats', 'sad_fox_or_mad_banana','sad_pandas_and_happy_cats_for_people'] 
replacement_s = '_1_' 
lookup = ['for', 'or', 'and'] 
lookup = [x.join('_'*2) for x in lookup] #Changing to: ['_for_', '_or_', '_and_'] 
results = [] 
for i,item in enumerate(l): 
    for s in lookup: 
     if s in item: 
      l[i] = l[i].replace(s,'_1_') 
    results.extend(l[i].split('_1_')) 

उत्पादन:

['happy_feet', 'happy_hats', 'cats', 'sad_fox', 'mad_banana', 'sad_pandas', 'happy_cats', 'people'] 
संबंधित मुद्दे