Вопрос по generator-expression, python, dictionary, string, list-comprehension – преобразовать строку в dict, используя понимание списка

15

Я сталкивался с этой проблемой несколько раз и, похоже, не могу найти простого решения. Скажи у меня есть строка

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)

Но мне не очень нравится этот цикл for. Кажется, он настолько прост, что вы сможете преобразовать его в какое-то выражение для понимания списка. И это работает для немного более простых случаев, когдаval может быть строкой.

dic = dict([entry.split('=') for entry in list])

Однако мне нужно преобразовать val в int на лету, и делать что-то подобное синтаксически некорректно.

dic = dict([[entry[0], int(entry[1])] for entry.split('=') in list])

Итак, мой вопрос: есть ли способ устранить цикл for, используя понимание списка? Если нет, есть ли какой-нибудь встроенный метод python, который сделает это для меня?

Примечание. Не используйте встроенные функции в качестве имен переменных (string, list, так далее.) John Howard

Ваш Ответ

8   ответов
-3


Поскольку у вас уже есть строка, похожая на то, как вы ее пишете, вы можете просто адаптировать ее к синтаксису python и затем выполнить eval () it :)

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 и оцените ее. НО, конечно, вы должны выполнить дополнительные проверки работоспособности, чтобы убедиться, что код не введен туда!

Вы хотели сохранить это простым? не быть злым или не выбирать кого-то, но где это просто?
1
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}
Nice ......... 15.
29

>>> dict( (n,int(v)) for n,v in (a.split('=') for a in string.split() ) )
{'a': 0, 'c': 3, 'b': 1}
Да, это то, что я искал. Спасибо. @ Брайан: Я начинаю думать, что, возможно, держать это в цикле, вероятно, хорошая идея. Тем не менее, по крайней мере, теперь я знаю, как сделать это в одну строку. Pavel
@ Брайан Оукли: я согласен. На вопрос («есть ли способ устранить цикл for с использованием понимания списка») есть ответ. Тем не менее, ответ может быть не тем, что ониreally в розыске.
Хотя это круто, я думаю, что я предпочитаю версию в исходном вопросе с точки зрения долгосрочного обслуживания кода. Код в исходном вопросе ясен и очевиден, выше требуется несколько десятков секунд, чтобы заработать.
0

def kv(e): return (e[0], int(e[1]))
d = dict([kv(e.split("=")) for e in string.split(" ")])
2

особенно когда логика создания ключей и значений более сложна:

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

вероятно, вам следует использовать словарное понимание, представленное в 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
3

dict([x.split('=') for x in s.split()])
ОП хотел, чтобы второй элемент списка был приведен к целому числу.
3

 foo="a=0 b=1 c=3"
 ans=eval( 'dict(%s)'%foo.replace(' ',',')) )
 print ans
{'a': 0, 'c': 3, 'b': 1}
я знаю, как работает eval, но мне трудно это понять
Мне понадобилось время, чтобы понять ..
Функция foo.replace () включает «a = 0 b = 1 c = 3» в "a = 0, b = 1, c = 3". Форматирование строки создает новую строку «dict (a = 0, b = 1, c = 3)». Оценка этой строки дает желаемый диктат.

Похожие вопросы