2008-10-09 8 views
64

У меня есть строка, которая выглядит следующим образом:Расщепление разделенных точкой с запятой строка в словаре, в Python

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

Есть встроенный класс/функции в Python, который будет принимать эту строку и построить словарь, как если бы я это сделал:

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

Я просмотрел доступные модули, но не могу найти ничего, что соответствует.


Спасибо, я знаю, как сделать соответствующий код сам, но поскольку такие низковат решения, как правило, минные поля, ожидающие произойдет (то есть кто-то пишет:. Name1 = «Value1 = 2»;) и т.д. то я обычно предпочитаю некоторые предварительно проверенные функции.

Тогда я сделаю это сам.

+0

ваш вопрос требует поддержки `s = r'Name1 = 'Value = 2'; Name2 = Value2; Name3 = Value3; Name4 =" Va \ "lue; \ n3" '' input (примечание: точка с запятой внутри цитируемой строка, цитата экранирована с помощью обратного слэша, используется `\ n` escape, используются как одиночные, так и двойные кавычки)? – jfs 2014-12-21 20:42:20

+0

Этот вопрос мне старше 6 лет, код, который был связан с этим, давно уже заменен :) И нет, это не требовало поддержки кавычек. Я просто хотел, чтобы у меня была предварительно построенная f вместо того, чтобы писать что-то сам. Однако код давно ушел. – 2014-12-21 20:43:28

ответ

100

Там нет встроенной, но вы можете сделать это довольно просто с генератором понимания:

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

в зависимости от точной структуры вашего формата, вам, возможно, придется написать свой собственный простой парсер, однако.

+0

код не обрабатывает цитирование, попробуйте: `s =" Name1 = 'Value; 2'; Name2 = Value2; Name3 = Value3 "` (примечание: точка с запятой в указанном значении `Name1`). – jfs 2014-12-21 20:18:41

4

Это происходит близко к делать то, что вы хотели:

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

он ломается, если на входе есть `&` или `%`. – jfs 2014-12-21 20:59:10

-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` (как в Kyle), получится правильно, в то время как ваш повысит значение ValueError , OP конкретно говорит, что «такие небольшие решения, как правило, ждут мои очереди», поэтому он хочет встроенное или другое хорошо протестированное решение, и он приводит пример, который нарушит ваш код. – abarnert 2013-03-27 00:05:53

-1

ЕСЛИ ваш значение1, значение2 просто заполнители для фактических значений, можно также использовать функцию 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

Это может быть просто сделать строку соединения и список понимание

», 'присоединиться ([' % s =% s'% х ​​для х в d.Items()])

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