преобразовать строку в DICT с использованием понимания списка
-
12-09-2019 - |
Вопрос
Я сталкивался с этой проблемой несколько раз и не могу найти простое решение. Скажи, что у меня есть строка
string = "a=0 b=1 c=3"
Я хочу преобразовать это в словарь, а A, B и C - ключ, а 0, 1 и 3 - их соответствующие значения (преобразованы в Int). Очевидно, я могу сделать это:
list = string.split()
dic = {}
for entry in list:
key, val = entry.split('=')
dic[key] = int(val)
Но мне не очень нравится это для Loop, это кажется настолько простым, что вы сможете преобразовать его в какое -то выражение понимания списка. И это работает для немного более простых случаев, когда val
может быть строкой.
dic = dict([entry.split('=') for entry in list])
Тем не менее, мне нужно преобразовать Val в Int на лету, и делать что -то подобное, синтаксически неверно.
dic = dict([[entry[0], int(entry[1])] for entry.split('=') in list])
Итак, мой вопрос: есть ли способ исключить цикл для понимания списка? Если нет, есть ли какой -то встроенный метод Python, который сделает это для меня?
Решение
Вы имеете в виду это?
>>> dict( (n,int(v)) for n,v in (a.split('=') for a in string.split() ) )
{'a': 0, 'c': 3, 'b': 1}
Другие советы
Как насчет одной строки без понимания списка?
foo="a=0 b=1 c=3"
ans=eval( 'dict(%s)'%foo.replace(' ',',')) )
print ans
{'a': 0, 'c': 3, 'b': 1}
Попробуйте следующее:
dict([x.split('=') for x in s.split()])
Мне иногда нравится этот подход, особенно когда логика для изготовления ключей и значений более сложна:
s = "a=0 b=1 c=3"
def get_key_val(x):
a,b = x.split('=')
return a,int(b)
ans = dict(map(get_key_val,s.split()))
В настоящее время вы, вероятно, должны использовать понимание словаря, представленное в 2.7:
mydict = {key: int(value) for key, value in (a.split('=') for a in mystring.split())}
Понимание словаря быстрее и блестящее (и, на мой взгляд, более читаемо).
from timeit import timeit
setup = """mystring = "a=0 b=1 c=3\""""
code1 = """mydict = dict((n,int(v)) for n,v in (a.split('=') for a in mystring.split()))""" # S.Lott's code
code2 = """mydict = {key: int(value) for key, value in (a.split('=') for a in mystring.split())}"""
print timeit(code1, setup=setup, number=10000) # 0.115524053574
print timeit(code2, setup=setup, number=10000) # 0.105328798294
from cgi import parse_qsl
text = "a=0 b=1 c=3"
dic = dict((k, int(v)) for k, v in parse_qsl(text.replace(' ', '&')))
print dic
отпечатки
{'a': 0, 'c': 3, 'b': 1}
Я бы сделал это:
def kv(e): return (e[0], int(e[1]))
d = dict([kv(e.split("=")) for e in string.split(" ")])
Мне нравится решение С.лотта, но я придумал другую возможность.
Поскольку у вас уже есть строка, напоминающая так, как вы пишете, вы можете просто адаптировать ее к синтаксису Python, а затем Engain (). :)
import re
string = "a=0 b=1 c=3"
string2 = "{"+ re.sub('( |^)(?P<id>\w+)=(?P<val>\d+)', ' "\g<id>":\g<val>,', string) +"}"
dict = eval(string2)
print type(string), type(string2), type(dict)
print string, string2, dict
Здесь довольно грубое и не поймает всех возможных идентификаторов Python, но я хотел сделать это простым ради простоты. Конечно, если у вас есть контроль над тем, как генерируется входная строка, просто генерируйте ее в соответствии с синтаксисом Python и оцените ее. Но, конечно, вы должны выполнить дополнительные проверки здравомыслия, чтобы убедиться, что там нет кода!