15

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

string = "a=0 b=1 c=3" 

Я хочу, чтобы преобразовать его в словарь с а, б и является ключевым и 0, 1 и 3 являются их соответствующие значения (преобразованная в целое). Очевидно, что я могу это сделать:

list = string.split() 
    dic = {} 
    for entry in list: 
     key, val = entry.split('=') 
     dic[key] = int(val) 

Но мне не очень нравится, что цикл, кажется, так просто, что вы должны быть в состоянии преобразовать его в какой-то выражения списка понимания. И это работает в более простых случаях, когда 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, который сделает это для меня?

+0

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

ответ

29

Вы имеете в виду это?

>>> dict((n,int(v)) for n,v in (a.split('=') for a in string.split())) 
{'a': 0, 'c': 3, 'b': 1} 
+4

Хотя это круто, я думаю, что я предпочитаю версию в оригинальный вопрос с долгосрочной код обслуживания. Код в исходном вопросе ясен и ясен, для этого требуется несколько десятков секунд. –

+1

@ Брайан Оукли: Согласен. Вопрос («есть ли способ устранить цикл for, используя понимание списка»), имеет ответ. Однако ответ может быть не тем, что они действительно хотели. –

+1

Да, это то, что я искал. Спасибо. @Bryan: Я начинаю думать, что, возможно, сохранение этого для цикла, вероятно, хорошая идея. Тем не менее, по крайней мере сейчас я знаю, как это сделать в одной строке. – Pavel

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} 
+0

Ницца ......... 15. –

-3

Мне нравится решение С. Лотт, но я придумал еще одну возможность.
Поскольку у вас уже есть строка, напоминающего как-то так, как вы пишете, что вы можете просто адаптировать его к синтаксису питона, а затем Eval() это :)

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 

Регулярное выражение здесь довольно сырой и выиграл» t улавливать все возможные идентификаторы python, но я хотел сохранить его простым для простоты. Конечно, если у вас есть контроль над тем, как генерируется входная строка, просто сгенерируйте ее в соответствии с синтаксисом python и пропустите ее. НО, конечно, вы должны выполнить дополнительные проверки работоспособности, чтобы убедиться, что там не вводится код!

+2

Вы хотели сохранить это просто? не быть злым или никого не выбирать, но где это просто? – Nope

3

Как насчет однострочного без понимания списка?

foo="a=0 b=1 c=3" 
ans=eval('dict(%s)'%foo.replace(' ',','))) 
print ans 
{'a': 0, 'c': 3, 'b': 1} 
+0

Я знаю, как работает eval, но мне трудно понять это. – Ajay

+1

foo.replace() превращает «a = 0 b = 1 c = 3» в «a = 0, b = 1, c = 3». Форматирование строки создает новую строку «dict (a = 0, b = 1, c = 3)». Eval'ing, что строка производит желаемый dict. –

+0

Мне потребовалось некоторое время, чтобы понять .. – Ajay

3

Попробуйте следующее:

dict([x.split('=') for x in s.split()]) 
+1

OP хотел, чтобы второй элемент списка был отлит целым числом. – hughdbrown

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())) 
0

Я хотел бы сделать это:

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

В настоящее время вы hould, вероятно, использовать словарь понимание, введенный в 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 
Смежные вопросы