2013-06-08 4 views
0

Я хотел бы автоматизировать форму dictionary из файлов, которые имеют следующую структуру.Построение оригинального словаря из файла (python)

str11 str12 str13 
str21 str22 
str31 str32 str33 str34 
... 

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

{str11:(str12,str13),str21:(str22),str31:(str32,str33,str34), ... } 

(т.е. все записи str*1 ключи - все они разные - а остальные являются values) , Что я могу использовать?

+0

Есть ли повторяющиеся записи в первой колонке? – Sheng

+1

Нет, все они разные. Спасибо за вопрос. Я включу это. –

ответ

4
>>> with open('abc') as f: 
...  dic = {} 
...  for line in f: 
...   key, val = line.split(None,1) 
...   dic[key] = tuple(val.split()) 
...   
>>> dic 
{'str31': ('str32', 'str33', 'str34'), 
'str21': ('str22',), 
'str11': ('str12', 'str13')} 

Если вы хотите, чтобы порядок элементов должны быть сохранены затем рассмотреть вопрос об использовании OrderedDict:

>>> from collections import OrderedDict 
>>> with open('abc') as f: 
     dic = OrderedDict() 
     for line in f: 
      key, val = line.split(None,1) 
      dic[key] = tuple(val.split()) 
...   
>>> dic 
OrderedDict([ 
('str11', ('str12', 'str13')), 
('str21', ('str22',)), 
('str31', ('str32', 'str33', 'str34')) 
]) 
+0

Является ли 'len (dic ['str21'])' 1 или 2? – ASGM

+0

Это 1; синтаксис '(foo,)' означает одноэлементный кортеж – Kos

+1

@ASGM Это 1, кортеж с одним элементом имеет конечную запятую. –

2

Использование StringIO экземпляра для простоты:

import io 
fobj = io.StringIO("""str11 str12 str13 
str21 str22 
str31 str32 str33 str34""") 

Одна линия делает трюк:

>>> {line.split(None, 1)[0]: tuple(line.split()[1:]) for line in fobj} 
{'str11': ('str12', 'str13'), 
'str21': ('str22',), 
'str31': ('str32', 'str33', 'str34')} 

Обратите внимание на line.split(None, 1). Это ограничивает разделение на один элемент, потому что мы должны использовать .split() дважды в понимании dict. Мы не можем хранить промежуточные результаты для повторного использования, как в цикле. Значение None означает разделение на любые пробелы.

Для OrderedDict вы можете уйти с одной линии, используя выражение генератора:

from collections import OrderedDict 

>>> OrderedDict((line.split(None, 1)[0], tuple(line.split()[1:])) 
       for line in fobj) 
OrderedDict([('str11', ('str12', 'str13')), ('str21', ('str22',)), 
      ('str31', ('str32', 'str33', 'str34'))]) 
Смежные вопросы