2016-11-10 3 views
0

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

chrY 6 8 + 
chrY 3 5 + 
chrX 10 11 + 
chrX 13 15 - 

Мой желаемый результат будет:

{'chrY': {'+' : {'start': [3 , 6], 'end': [5, 8]}}, 'chrX': {'+' : {'start': [10], 'end': [11]} , '-': {'start' : [13], 'end' : [15]}}} 

Мой код до сих пор состоит из:

import sys 
first_dict = {} 
intron_dict = {} 
def main(): 
    with open(sys.argv[1], 'r') as intron: 
     for line in intron.readlines(): 
      line = line.split() 
      chromosome = line[0] 
      start = line[1] 
      end = line[2] 
      strand = line[3] 
      first_dict = {chromosome : (strand, start, end)} 

      for k, v in first_dict.iteritems(): 
       intron_dict.setdefault(k, []).append(v) 
     print (intron_dict) 
if __name__=='__main__': 
    main() 

Этот код позволяет мне сортировать chrY и chrX, не перезаписывая значения. У меня возникают проблемы с объединением ключей «+» и «-» и получением данных в желаемый формат. До сих пор мой выход выглядит следующим образом:

{'chrY': [('+', '6', '8'), ('+', '3', '5')], 'chrX': [('+', '10', '11'), ('-', '13', '15')]} 

ответ

0

Вы могли бы упростить код совсем немного, используя вложенную defaultdict, где значения на третьем уровне находятся списки:

from collections import defaultdict 

result = defaultdict(lambda: defaultdict(lambda: defaultdict(list))) 

with open('test.txt') as f: 
    for row in f: 
     ch, start, end, op = row.split() 
     result[ch][op]['start'].append(start) 
     result[ch][op]['end'].append(end) 

import json 
print(json.dumps(result, indent=4)) 

Выход:

{ 
    "chrY": { 
     "+": { 
      "start": [ 
       "6", 
       "3" 
      ], 
      "end": [ 
       "8", 
       "5" 
      ] 
     } 
    }, 
    "chrX": { 
     "+": { 
      "start": [ 
       "10" 
      ], 
      "end": [ 
       "11" 
      ] 
     }, 
     "-": { 
      "start": [ 
       "13" 
      ], 
      "end": [ 
       "15" 
      ] 
     } 
    } 
} 
0

Один из способов - использовать defaultdict. Для exmaple:

import sys 
from pprint import pprint 
from collections import defaultdict 

first_dict = defaultdict(dict) 
intron_dict = {} 

d = dict() 


def main(): 
    with open('test.csv', 'r') as intron: 
     for line in intron.readlines(): 
      chromosome, start, end, strand, = line.split() 

      if strand not in first_dict[chromosome]: 
       first_dict[chromosome][strand] = defaultdict(list) 

      first_dict[chromosome][strand]['start'].append(start) 
      first_dict[chromosome][strand]['end'].append(end) 

    pprint(first_dict) 

if __name__=='__main__': 
    main() 

Результаты в:

defaultdict(<class 'dict'>, 
      {'chrX': {'+': defaultdict(<class 'list'>, 
             {'end': ['11'], 
             'start': ['10']}), 
         '-': defaultdict(<class 'list'>, 
             {'end': ['15'], 
             'start': ['13']})}, 
      'chrY': {'+': defaultdict(<class 'list'>, 
             {'end': ['8', '5'], 
             'start': ['6', '3']})}}) 
0

Вот еще один способ без defaultdict. Только с помощью if ... else

import sys 
intron_dict = dict() 
def main(): 
    with open(sys.argv[1], 'r') as intron: 
     for line in intron.readlines(): 
      line = line.split() 
      chromosome = line[0] 
      start = int(line[1]) # converted to int to avoid quotes in result 
      end = int(line[2]) 
      strand = line[3] 
      first_dict = {strand : {'start' : [start], 'end' : [end]}} 

      if intron_dict.has_key(chromosome): 
       if intron_dict[chromosome].has_key(strand): 
        intron_dict[chromosome][strand]['start'].append(start) 
        intron_dict[chromosome][strand]['end'].append(end) 
       else: 
        intron_dict[chromosome][strand] = first_dict[strand] 
      else: 
       intron_dict.setdefault(chromosome, first_dict) 

     print (intron_dict) 

if __name__=='__main__': 
    main() 

Выход:

{'chrY': {'+': {'start': [6, 3], 'end': [8, 5]}}, 'chrX': {'+': {'start': [10], 'end': [11]}, '-': {'start': [13], 'end': [15]}}} 
Смежные вопросы