2015-06-29 2 views
3

Я создал словарь, используя этот код:исправляющие значения в словаре

import collections 

exons = collections.defaultdict(list) 
with open('test_coding.txt') as f: 
    for line in f: 
     chrom, start, end, isoform = line.split() 
     exons[isoform].append((int(start), int(end))) 

Этот код производит словарь, который выглядит так:

{'NM_100': [(75, 90), (100, 120)], 'NM_200': [(25, 50), (55, 75), (100, 125), (155, 200)]}) 

из этого файла:

chr1 75 90 NM_100 
chr1 100 120 NM_100 
chr2 25 50 NM_200 
chr2 55 75 NM_200 
chr2 100 125 NM_200 
chr2 155 200 NM_200 

Что я хочу сделать, это вычесть первое значение в списке (в первом случае, 75 и 25 для второго случая) от каждого г значение в конкретном списке для требуемого выхода:

{'NM_100': [(0, 15), (25, 45)], 'NM_200': [(0, 25), (30, 50), (75, 100), (130, 175)]}) 

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

def read_exons(line): 
    parts = iter(line.split()) #I think the problem is here 
    chrom = next(parts) 
    start = next(parts) 
    end = next(parts) 
    base = start[0] #and here 
    return name, [(s-base, e-base) for s, e in zip(start, end)] 

with open('testing_coding.txt') as f: 
    exons = dict(read_exons(line) for line in f 
     if not line.strip().startswith('#')) 

Любые предложения?

ответ

1

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

Проблема с попыткой сделать это без отдельного словаря или списка состоит в том, что если для первой строки вы выполняете вычитание, то для всех остальных значений, которые читаются, вы получите вычитание 0, что является новое значение первого элемента. Или вам придется сначала создать dict, а затем повторить его, чтобы сделать вычитание.

Пример -

import collections 

exons = collections.defaultdict(list) 
firstvalues = {} 
with open('test_coding.txt') as f: 
    for line in f: 
     chrom, start, end, isoform = line.split() 
     if isoform not in firstvalues: 
      firstvalues[isoform] = int(start) 
     exons[isoform].append((int(start) - firstvalues[isoform], int(end) - firstvalues[isoform])) 
+0

Я попытался использовать этот пример, но я продолжаю получать ошибку: 'TypeError: неподдерживаемый тип операндов для -: 'str' и 'str'' для последней строки. Нужно ли делать значения 'start' и' firstvalues ​​[isoform] 'integers независимо? – interstellar

+0

Да, вам нужно сделать их целыми числами. Позвольте мне уточнить это в ответ. –

+0

Обновлен ответ. –

0
for key, value in exons.items(): 
    s = value[0][0] 
    exons[key] = [(x[0] - s, x[1]) for x in value] 
+0

Это дало мне ValueError. 'слишком много значений для распаковки – interstellar

+0

@interstellar Извините, я отредактировал свой ответ, я забыл использовать' .items() '. – Delgan

2

Мой подход заключается в сохранении элемента, который вы хотите вычитать на каждой итерации, а затем применить его с помощью функции map, очень простой и сохранить результат на том же словаре:

exons = {'NM_100': [(75, 90), (100, 120)], 'NM_200': [(25, 50), (55, 75), (100, 125), (155, 200)]} 

for k,v in exons.items(): 
    x = d1[k][0][0] #Saving the first element of first tuple of each list 
    for i,t in enumerate(v): 
     exons[k][i] = tuple(map(lambda s: s-x, t)) #just to conserve the original format of your exons dictionany 

Выход:

>>> exons 
{'NM_100': [(0, 15), (25, 45)], 'NM_200': [(0, 25), (30, 50), (75, 100), (130, 175)]} 

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

  • Нет связанных вопросов^_^