Элегантный способ преобразования строки в dict и обратно

#python #string #dictionary #type-conversion

#python #строка #словарь #преобразование типов

Вопрос:

Существует ли элегантный однострочный способ преобразования этого типа строки в dict? Я гуглил уже час, но без нескольких циклов разделения строк я не могу заставить его работать.

 Input  = "2:9, 6:90, 7:60"
Output = {'2': 9, '6': 90, '7': 60}
 

Мне также понадобится обратная операция от dict к string .

Комментарии:

1. Пожалуйста, предоставьте больше информации о том, как будет работать это преобразование. Почему целочисленный ключ внезапно становится строковым?

2. {key: int(val) for key, val in map(lambda x: x.strip().split(':'), Input.split(','))} но это настолько уродливо, что никто не должен его использовать. нет ничего постыдного в использовании нескольких строк для такого преобразования

3. для развлечения, вот еще одно идеальное решение, основанное на регулярных выражениях: {key: int(val) for key, val in re.findall('(?P<key>d ):(?P<val>d )', Input)}

4. я не боюсь нескольких строк. как новичку, мне было больше интересно, есть ли более элегантный способ python, чем несколько строк. слишком часто случается, что я пишу много кода с несколькими циклами и т. Д., А затем я узнаю, что в python есть простое однострочное решение 🙂 спасибо за помощь!

Ответ №1:

С точки зрения производительности наиболее эффективным будет обычный for цикл:

 my_string = "2:9, 6:90, 7:60"
my_dict = {}
for s in my_string.split(', '):
     k, v = s.split(":")
     my_dict[k] = int(v)
 

где my_dict будет содержаться:

 >>> my_dict
{'2': 9, '7': 60, '6': 90}
 

Чтобы вернуть ту же строку, вы можете выполнить .join() dict.items() как:

 >>> ", ".join("{}:{}".format(k, v) for k, v in my_dict.items())
'2:9, 7:60, 6:90'
 

Или вы также можете преобразовать dict в string и выполнить для него некоторое форматирование, например:

 >>> str(my_dict)[1:-1].replace(": ", ":").replace("'", "")
'2:9, 7:60, 6:90'
 

Комментарии:

1. большое вам спасибо! этот цикл for намного элегантнее, чем моя версия с несколькими циклами 🙂 Мне нужно улучшить синтаксис pythons. Это абсолютно ясно для меня, когда я читаю ваш код, но я думаю, что сам бы никогда не разобрался в этом :/

Ответ №2:

Ну, не задавая вопросов, если вам нужна однострочная строка, которая превращает ключ в строку, а значение в int:

 dict([[j[0].strip(), int(j[1])] for j in [i.split(':') for i in Input.split(',')]])
 

Комментарии:

1. это был бы идеальный ответ! Я по-прежнему придерживаюсь ответа Moinuddins, поскольку он более удобочитаем для меня, как для новичка, и уже претерпел повторное преобразование. спасибо за ваши усилия! это высоко ценится!

Ответ №3:

Вы можете использовать ast.literal_eval и ставить скобки на каждом конце строки, хотя ваши ключи будут целыми числами, а не строками.

 from ast import literal_eval

Input  = "2:9, 6:90, 7:60"

Output = literal_eval(f"{{{input}}}")
 

 {2: 9, 6: 90, 7: 60}
 

Чтобы исправить вывод в виде строковых ключей, просто преобразуйте их вручную

 Output = dict(zip(map(str, Output), Output.values()))
 

 {'2': 9, '7': 60, '6': 90}
 

Без импорта каких-либо библиотек, которые вам нужно будет использовать str.split

 Output = dict(s.split(':') for s in Input.split(', '))
 

 {'2': '9', '6': '90', '7': '60'}
 

Хотя теперь ваши значения являются строками, поэтому вам нужно это исправить.

 Output = dict(zip(Output, map(int, Output.values())))
 

 {'2': 9, '7': 60, '6': 90}