2012-03-07 2 views
-3

Мой список:Как сделать словарь из списка

list = ['name1', 'option1.1 value1.1', 'option1.2 value1.2', 'name2', 'option2.1 value2.1', 'option2.2 value2.2', 'option2.3 value2.3'] 

И я хочу создать словарь, как это:

dict = {'name1':{'option1.1':'value1.1', 'option1.2':'value1.2'}, 'name2':{'option2.1': 'value2.1', 'option2.2':'value2.2', 'option2.3':'value2.3'} 

Я не знаю, насколько велик мой список (количество имен, опции и значения). Есть идеи?

+0

Какова ваша информация о каждом наборе данных? У вас может быть переменное количество опций для каждого имени, но имя никогда не будет отформатировано 'option.name' или' value.name', а опции и значения всегда будут иметь 'option.' и' value.' на передней панели, правильно ? –

+3

Вы что-то пробовали? Поскольку у вас нет определенной длины для каждого набора, вам придется перебирать каждый элемент и действовать на значение, содержащее «имя», чтобы начать новый ключ, который является новым словарем. – jdi

+1

. Откуда вы знаете, какие элементы в списке « имена "и которые являются" опциями "? Откуда взялись данные? –

ответ

1

Предполагая, что имя всегда будет один маркер (также, не используйте список и Dict в качестве имен переменных, так как они являются встроенные функции):

result = {} 
for val in my_list: 
    split_val = val.split() 
    if len(split_val) == 1: 
     last_name = split_val[0] 
     result[last_name] = {} 
    else: 
     result[last_name][split_val[0]] = split_val[1] 

Обратите внимание, что это будет душить, если список плохо отформатированный и первое значение не является именем.

+0

вы можете избежать последнего, предоставив разумное значение по умолчанию для 'last_name' (просто добавьте' last_name = 'noname'' перед циклом). С другой стороны, «ошибки никогда не должны проходить молча», вы знаете – georg

+0

@ thg435 У меня по умолчанию был дефолт, но я подумал, что на самом деле не должно работать. Тем не менее, некоторая более эффективная обработка ошибок для случая. –

2

со списком и Dict понимания:

id=[b[0] for b in enumerate(lst) if 'name' in b[1]]+[None] 
d={lst[id[i]]:dict(map(str.split,lst[id[i]+1:id[i+1]])) for i in range(len(id)-1)} 

ваш первоначальный список был здесь назван lst

Это, возможно, не читаемыми в качестве ответа по @sr22222, но, возможно, это быстрее, и дело вкуса ,

+0

Я не думаю, что это сработает. Если имя не содержит имени или имеется более одной пары опций/значений для имени, не будет ли это задушить? –

+0

это работает, просто попробуйте. –

+0

Я просто попробовал это с тривиальным примером, и это провалилось. 'lst = ['foon', 'fooopt.1 fooval.1', 'fooopt.2 fooval.2', 'barn', 'baropt.1 barval.1']' дал {} для b. Я думаю, что «если« имя »в b [1]' должно быть 'if len (b [1]). Split() == 1'. Редактировать: даже при этом он пропускает «сарай». –

Смежные вопросы