2008-10-09 7 views
64

में मैं एक स्ट्रिंग है कि इस तरह दिखता है:विभाजन एक शब्दकोश में एक अर्धविराम द्वारा अलग किए स्ट्रिंग, अजगर

"Name1=Value1;Name2=Value2;Name3=Value3" 

वहाँ है एक अंतर्निहित पायथन में वर्ग/समारोह है कि कि स्ट्रिंग लेने के लिए और एक का निर्माण करेगी शब्दकोश, जैसा कि मैंने यह किया था:

dict = { 
    "Name1": "Value1", 
    "Name2": "Value2", 
    "Name3": "Value3" 
} 

मैंने उपलब्ध मॉड्यूल को देखा है लेकिन मेल खाने वाले कुछ भी नहीं मिल रहे हैं।


धन्यवाद, मैं कितना प्रासंगिक कोड अपने आप को बनाने के लिए पता है, लेकिन जब से इस तरह छोटा सा समाधान आमतौर पर होने के लिए इंतजार कर रहे खदान क्षेत्र हैं (यानी कोई लिखते हैं:। NAME1 = 'VALUE1 = 2';) आदि तो मैं आमतौर पर कुछ पूर्व परीक्षण समारोह पसंद करते हैं।

मैं इसे स्वयं कर दूंगा।

+0

क्या आपके प्रश्न को 's = r'Name1 = 'value = 2' का समर्थन करने की आवश्यकता है; नाम 2 = मान 2; नाम 3 = मान 3; नाम 4 =" वीए \ "ल्यू; \ n3" 'इनपुट (नोट: उद्धृत के अंदर एक अर्धविराम स्ट्रिंग, बैकस्लैश का उपयोग करके एक उद्धरण बच निकला है, '\ n' भागने का उपयोग किया जाता है, एकल और डबल कोट्स दोनों का उपयोग किया जाता है)? – jfs

+0

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

उत्तर

100

कोई अंतर्निहित है, लेकिन आप एक जनरेटर समझ के साथ काफी बस यह पूरा कर सकते हैं:

s= "Name1=Value1;Name2=Value2;Name3=Value3" 
dict(item.split("=") for item in s.split(";")) 

[संपादित करें] अपने अद्यतन से आप दर्शाते हैं कि आप के हवाले से संभाल करने के लिए आवश्यकता हो सकती है। यह चीजों को जटिल करता है, इस पर निर्भर करता है कि आप किस सटीक प्रारूप की तलाश कर रहे हैं (क्या उद्धरण वर्ण स्वीकार किए जाते हैं, क्या बचने के पात्र आदि)। आप यह देखने के लिए सीएसवी मॉड्यूल देखना चाहते हैं कि यह आपके प्रारूप को कवर कर सकता है या नहीं। यहां एक उदाहरण दिया गया है: (ध्यान दें कि एपीआई इस उदाहरण के लिए थोड़ा उलझन में है, क्योंकि सीएसवी को रिकॉर्ड्स के अनुक्रम के माध्यम से पुन: स्थापित करने के लिए डिज़ाइन किया गया है, इसलिए .next() कॉल मैं केवल पहली पंक्ति को देखने के लिए बना रहा हूं। समायोजित करें आपकी आवश्यकताओं के अनुरूप):

>>> s = "Name1='Value=2';Name2=Value2;Name3=Value3" 

>>> dict(csv.reader([item], delimiter='=', quotechar="'").next() 
     for item in csv.reader([s], delimiter=';', quotechar="'").next()) 

{'Name2': 'Value2', 'Name3': 'Value3', 'Name1': 'Value1=2'} 

अपने प्रारूप की सटीक संरचना के आधार पर आप फिर भी अपने स्वयं के सरल पार्सर लिखने के लिए आवश्यकता हो सकती है।

+0

कोड उद्धरण संभाल नहीं करता है, कोशिश करें: 's =" name1 = 'मान; 2'; नाम 2 = मान 2; नाम 3 = मान 3 "' (नोट: उद्धृत 'नाम 1' मान में अर्धविराम)। – jfs

4

यह करने के लिए करीब आता है कि तुम क्या चाहते थे:

>>> import urlparse 
>>> urlparse.parse_qs("Name1=Value1;Name2=Value2;Name3=Value3") 
{'Name2': ['Value2'], 'Name3': ['Value3'], 'Name1': ['Value1']} 
+1

इनपुट में '&' या '%' होने पर यह टूट जाता है। – jfs

-2
easytiger $ cat test.out test.py | sed 's/^/ /' 
p_easytiger_quoting:1.84563302994 
{'Name2': 'Value2', 'Name3': 'Value3', 'Name1': 'Value1'} 
p_brian:2.30507516861 
{'Name2': 'Value2', 'Name3': "'Value3'", 'Name1': 'Value1'} 
p_kyle:7.22536420822 
{'Name2': ['Value2'], 'Name3': ["'Value3'"], 'Name1': ['Value1']} 
import timeit 
import urlparse 

s = "Name1=Value1;Name2=Value2;Name3='Value3'" 

def p_easytiger_quoting(s): 
    d = {} 
    s = s.replace("'", "") 
    for x in s.split(';'): 
     k, v = x.split('=') 
     d[k] = v 
    return d 


def p_brian(s): 
    return dict(item.split("=") for item in s.split(";")) 

def p_kyle(s): 
    return urlparse.parse_qs(s) 



print "p_easytiger_quoting:" + str(timeit.timeit(lambda: p_easytiger_quoting(s))) 
print p_easytiger_quoting(s) 


print "p_brian:" + str(timeit.timeit(lambda: p_brian(s))) 
print p_brian(s) 

print "p_kyle:" + str(timeit.timeit(lambda: p_kyle(s))) 
print p_kyle(s) 
+0

यह सवाल का जवाब नहीं देता है, क्योंकि यह उद्धरण संभाल नहीं करता है। कोशिश करें 's =" name1 = 'Value1 = 2'; name2 = Value2 "और' csv' (ब्रायन के स्वीकृत उत्तर में) या 'parse_qs' (जैसा कि काइल में है) इसे सही लगेगा, जबकि आपका' ValueError 'उठाएगा । ओपी विशेष रूप से कहता है "ऐसे छोटे समाधान आमतौर पर मेरे खेतों का इंतजार कर रहे हैं", यही कारण है कि वह एक अंतर्निहित या अन्य अच्छी तरह से परीक्षण समाधान चाहता है, और वह एक उदाहरण देता है जो आपके कोड को तोड़ देगा। – abarnert

+0

आह मैंने उसे नहीं देखा। फिर भी। पुनरावृत्ति से पहले मुख्य स्ट्रिंग में उन लोगों को तैयार करने और हजारों बार प्रतिस्थापन समारोह को याद करने के लिए यह आपके सभी समाधानों से तेज़ होगा। मैं – easytiger

+0

अपडेट करूंगा, मुझे यकीन नहीं है कि आप इसे कैसे तैयार करेंगे। लेकिन अगर आप ऐसा करते हैं, तो ऐसा लगता है कि ओपी को एक साधारण समाधान में क्या डर था। क्या आप वाकई कोई और खान नहीं हैं? क्या आप ओपी की संतुष्टि को साबित कर सकते हैं? – abarnert

-1

अपने value1, value2 अगर सिर्फ वास्तविक मूल्यों के लिए प्लेसहोल्डर हैं, आप भी dict() समारोह संयोजन में eval() साथ उपयोग कर सकते हैं।

>>> s= "Name1=1;Name2=2;Name3='string'" 
>>> print eval('dict('+s.replace(';',',')+')') 
{'Name2: 2, 'Name3': 'string', 'Name1': 1} 

यह dict() समारोह वजह से वाक्य रचना dict(Name1=1, Name2=2,Name3='string') समझते हैं। स्ट्रिंग में रिक्त स्थान (उदा। प्रत्येक अर्धविराम के बाद) को अनदेखा कर दिया जाता है। लेकिन ध्यान दें कि स्ट्रिंग मानों को उद्धरण की आवश्यकता होती है।

+0

धन्यवाद, upvote string.replace अच्छी तरह से काम किया। पता नहीं क्यों मैं विभाजित नहीं कर सका। मैंने टी = बॉक्स पर i = textcontrol.GetValue() किया था, फिर o = i.split (';') लेकिन प्रतिस्थापन के विपरीत प्रारूप के बारे में शिकायत की गई स्ट्रिंग को आउटपुट नहीं किया था। – Iancovici

+1

's.replace (';'' उद्धृत मूल्य के अंदर ';' 'आधारित समाधान तोड़ता है;' [eval बुरा है] (http://stackoverflow.com/a/9558001/4279) और यह अनावश्यक है ये मामला। – jfs

0

यह बस स्ट्रिंग द्वारा किया जा सकता में शामिल होने और सूची समझ

','। में शामिल होने के ([ '% s =% s'% x d.items में एक्स() के लिए])

>>d = {'a':1, 'b':2} 
>>','.join(['%s=%s'%x for x in d.items()]) 
>>'a=1,b=2' 
संबंधित मुद्दे