在 Python 中,将分号分隔的字符串分割为 dictionary

我有一个这样的字符串:

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

Python 中是否有一个内置的 class/function,它将使用这个字符串并构造一个 dictionary,就好像我已经这样做了:

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

我已经检查了可用的模块,但似乎找不到任何匹配的。


谢谢,我确实知道如何自己编写相关的代码,但是由于这种小的解决方案通常是雷区等待发生(即。有人写: Name1 = ‘ Value1 = 2’;)等等,那么我通常更喜欢一些预先测试的函数。

那我自己来。

107044 次浏览

There's no builtin, but you can accomplish this fairly simply with a generator comprehension:

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

[Edit] From your update you indicate you may need to handle quoting. This does complicate things, depending on what the exact format you are looking for is (what quote chars are accepted, what escape chars etc). You may want to look at the csv module to see if it can cover your format. Here's an example: (Note that the API is a little clunky for this example, as CSV is designed to iterate through a sequence of records, hence the .next() calls I'm making to just look at the first line. Adjust to suit your needs):

>>> 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'}

Depending on the exact structure of your format, you may need to write your own simple parser however.

This comes close to doing what you wanted:

>>> import urlparse
>>> urlparse.parse_qs("Name1=Value1;Name2=Value2;Name3=Value3")
{'Name2': ['Value2'], 'Name3': ['Value3'], 'Name1': ['Value1']}
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)

IF your Value1, Value2 are just placeholders for actual values, you can also use the dict() function in combination with eval().

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

This is beacuse the dict() function understand the syntax dict(Name1=1, Name2=2,Name3='string'). Spaces in the string (e.g. after each semicolon) are ignored. But note the string values do require quoting.

It can be simply done by string join and list comprehension

",".join(["%s=%s" % x for x in d.items()])

>>d = {'a':1, 'b':2}
>>','.join(['%s=%s'%x for x in d.items()])
>>'a=1,b=2'
s1 = "Name1=Value1;Name2=Value2;Name3=Value3"


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