تقسيم سلسلة مفصولة منقوطة إلى القاموس، في بيثون

StackOverflow https://stackoverflow.com/questions/186857

سؤال

ولدي السلسلة التي يبدو مثل هذا:

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

هل هناك فئة / وظيفة المضمنة في بيثون من شأنها أن تأخذ هذه السلسلة وبناء القاموس، كما لو كنت قد فعلت هذا:

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

ولقد بحثت من خلال الوحدات المتاحة ولكن لا يمكن العثور على ما يبدو أي شيء يطابق.


شكرا، أنا لا أعرف كيف لجعل رمز ذات الصلة نفسي، ولكن لأن هذه الحلول الشريك الأصغر عادة ما تكون حقول الألغام في انتظار ان يحدث (أي شخص يكتب: NAME1 = 'VALUE1 = 2'؛) الخ ثم وعادة ما تفضل بعض ما قبل اختبار وظيفة.

وسأفعل ذلك بنفسي الحين.

هل كانت مفيدة؟

المحلول

وليس هناك المضمن، ولكن يمكنك تحقيق ذلك ببساطة إلى حد ما مع الفهم مولد:

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

على [تحرير] من التحديث التي تشير إلى أنك قد تحتاج إلى معالجة نقلا. هذا لا تعقيد الامور، اعتمادا على ما الشكل المحدد كنت تبحث عن (ما اقتبس تقبل حرف، حرف ما هروب الخ). قد ترغب في النظر في وحدة CSV لمعرفة ما اذا كان يمكن أن تغطي الشكل الخاص بك. وهنا مثال على ذلك: (لاحظ أن API هو عالي الكعب قليلا عن هذا المثال، كما تم تصميم CSV تكرار خلال سلسلة من السجلات، وبالتالي .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'}

واعتمادا على هيكل الدقيق للشكل الخاص بك، قد تحتاج إلى كتابة محلل بسيط الخاصة بك ولكن.

نصائح أخرى

وهذا يقترب من فعل ما تريد:

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

dict(map(lambda x: x.split('='), s1.split(';')))

ويمكن ان يتم ذلك ببساطة عن طريق سلسلة الانضمام إليها وقائمة على الفهم

'،' انضمام ([ '٪ ق =٪ ق'٪ خ ل x في d.items ()])

>>d = {'a':1, 'b':2}
>>','.join(['%s=%s'%x for x in d.items()])
>>'a=1,b=2'

وإذا كان لديك 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') بناء الجملة. يتم تجاهل المسافات في السلسلة (على سبيل المثال، بعد كل منقوطة). ولكن لاحظ قيم السلسلة لا تتطلب نقلا.

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)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top