У меня есть строка, которая выглядит так:
"Name1=Value1;Name2=Value2;Name3=Value3"
Есть ли в Python встроенный класс / функция, которая возьмет эту строку и создаст словарь, как если бы я сделал это:
dict = {
"Name1": "Value1",
"Name2": "Value2",
"Name3": "Value3"
}
Я просмотрел доступные модули, но не нашел ничего подходящего.
Спасибо, я знаю, как сам сделать соответствующий код, но поскольку такие небольшие решения обычно являются минными полями, ожидающими своего появления (например, кто-то пишет: Name1 = 'Value1 = 2';) и т. Д., То я обычно предпочитаю некоторые предварительные проверенная функция.
Я тогда сделаю это сам.
python
string
dictionary
split
Лассе В. Карлсен
источник
источник
s = r'Name1='Value=2';Name2=Value2;Name3=Value3;Name4="Va\"lue;\n3"'
ввода (примечание: точка с запятой внутри строки в кавычках, кавычка экранируется с помощью обратной косой черты,\n
используется escape, используются как одинарные, так и двойные кавычки)?Ответы:
Нет встроенной функции, но вы можете сделать это довольно просто с пониманием генератора:
s= "Name1=Value1;Name2=Value2;Name3=Value3" dict(item.split("=") for item in s.split(";"))
[Edit] В вашем обновлении вы указываете, что вам может потребоваться обработка цитирования. Это усложняет ситуацию, в зависимости от того, какой именно формат вы ищете (какие символы кавычек принимаются, какие escape-символы и т. Д.). Вы можете взглянуть на модуль 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'}
Однако в зависимости от точной структуры вашего формата вам может потребоваться написать собственный простой синтаксический анализатор.
источник
s = "Name1='Value;2';Name2=Value2;Name3=Value3"
(примечание: точка с запятой в цитируемомName1
значении).AttributeError: '_csv.reader' object has no attribute 'next'
меня бросает второй пример . Конечно, зналimport csv
.Это похоже на то, что вы хотели:
>>> 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(';')))
источник
Это можно просто сделать путем объединения строк и понимания списка.
",".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'
источник
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)
источник
s = "Name1='Value1=2';Name2=Value2" and
csv` (как в принятом ответе Брайана) илиparse_qs
(как в ответе Кайла) получите все правильно, в то время как ваш ответ повыситValueError
. В ОП конкретно говорится, что «такие небольшие решения обычно представляют собой минные поля, ожидающие своего появления», поэтому ему нужно встроенное или другое хорошо протестированное решение, и он приводит пример, который сломает ваш код.s.replace
ничего не делает; он просто возвращает новую строку, которую вы игнорируете. Во-вторых, даже если вы все поняли правильно (s = s.replace…
), это не решает проблему, а просто добавляет новую поверх нее. Попробуйте либо на моем примере, либо на OP.Name='Value1=2';
. И ваш код не справляется с этим. И я не уверен, как бы вы санировали это, не разбирая его каким-либо образом, который будет таким же медленным, какurlparse
илиcsv
в первую очередь.ЕСЛИ ваше 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')
. Пробелы в строке (например, после каждой точки с запятой) игнорируются. Но обратите внимание, что строковые значения требуют заключения в кавычки.источник
s.replace(';'
-основанное решение не работает, если оно находится;
внутри указанного значения. eval - зло, и в этом случае он не нужен.