2015-12-16 1 views
0

Я пытаюсь сделать словарь, где каждый ключ является именем (уникальной последовательности ДНК), а его значение будет списком других имен (которые имеют такой же последовательности ДНК). Например, {'2617': [['5632'], ['7630'], ...}. Я пытаюсь заполнить этот словарь из файла, который имеет такую ​​структуру:Добавить значения в ключ между экземплярами совпадения строк в Python

1. 11618 [82] 
11619 
11620 
12180 
    2. 12183 [1] 
    3. 12918 [2] 
12922 

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

unique_seqs=[] 
for line in in_file: 
    line=line.strip() 
    if '[' in line: 
     line=line.split() 
     unique_seqs.append(line[1]) 

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

1. 11618 [82] 
11619 
11620 
12180 
ML_S2470 
ML_S2472 
    2. 12183 [1] 
12922 
    3. 12919 [20] 
12920 
12921 

и код, который сделал мой список в последний комментарий ниже:

in_file = open('example.txt', 'r') 
for line in in_file: 
    line=line.strip() 
    line=line.split('\n') 
+0

Чтобы быть ясным, «11618» будет ключом от первой строки, а его значения будут следующими тремя строками? А следующий ключ «11620» будет иметь пустой список значений? – Reti43

+0

11618 будет ключом, и он будет иметь значения '[[11619], [11620], [12180]]'. «11620» не будет ключевым, поэтому у него не будет пустого списка значений. В действительности «11618» будет иметь список из 82 значений, указанных в скобках, следующих за «11618». Я пытаюсь написать код сейчас, чтобы воспользоваться тем фактом, что я «знаю», сколько значений должен иметь ключ. После этого ключ «12183» выше не будет иметь значения. – Jared

+0

Простите, мы имели в виду то же самое, я просто смутил цифры. – Reti43

ответ

1

Это, кажется, что вы хотите.

with open('example.txt', 'r') as in_file: 
    key = None 
    sequences = {} 

    for line in in_file: 
     if '.' in line: 
      if key: 
       sequences[key] = values 
      key = line.split()[1] 
      values = [] 
     else: 
      values.append([line[:-1].strip()]) 
    sequences[key] = values 

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

Первоначально у нас есть неопределенный ключ. Поскольку первая строка будет ключом, код войдет в блок if '.' in line: и попытается сопоставить любые значения до нашего ключа. Чтобы предотвратить это за один раз, отображение выполняется внутри блока if key:.

Я использовал if '.' in line, потому что он гарантированно будет найден ранее в строке, чем '['. Однако это вопрос предпочтения.

Лучше всего открыть файл с помощью синтаксиса with. Но даже если вы сделаете это как in_file = open(...), когда вы перебираете строки, они будут содержать новую строку в конце. Однако вам не нужно делать никаких преждевременных манипуляций с строкой. Сначала проверьте, является ли строка ключом или значением. line.split()[1], естественно, выберет ключевое значение для вас, не беспокоясь о том, чтобы удалить любые пробелы или новые строки. И если это значение, line[:-1] вернет строку без новой строки, из которой вы можете удалить пробелы.

+0

Так что я могу заставить это работать над вашим «фиктивным» примером с in_file как строкой, а затем разбить, но я не могу заставить его работать с моим полным файлом. Когда я печатаю ваш in_file, он выглядит так: «[116] [82]», «11619», «11620», «12180», «2. 12183 [1]», «3. 12918 [2] , '12922'] ', но когда я печатаю мое, это выглядит так:' ['1. 11618 [82]', ''] ['11619', ''] ['11620', ''] ' Эта другая структура сбрасывает ваш код. Я могу избавиться от последнего элемента в каждом списке, используя команду .strip(), но это не проблема. У вас есть какая-то проблема? Благодаря! – Jared

+0

Я думаю, проблема в том, что я генерирую список для каждой строки, '['1. 11618 [82] '] \ n [' 11619 '] \ n [' 11620 '] ', поэтому у меня есть список списков, а ваш - это всего лишь один список с каждым элементом, имеющим от 1 до 3 элементов' [' 1. 11618 [82] ',' 11619 ',' 11620 ',' 12180 ',' 2. 12183 [1] ',' 3. 12918 [2] ',' 12922 '] '. Я попытаюсь добавить код, который я использую, и фрагмент из файла в моем исходном вопросе выше, я не могу получить это форматирование! – Jared

+0

Хорошо, теперь я понимаю результат. 'line.split ('\ n')' будет возвращать список элементов, поэтому, если у вас есть строка 's = 'abc \ n'', она вернет' [' abc ',' '] '. Вы можете изменить это, выполнив 's.split ('\ n') [0]', но если вы будете следовать рекомендациям из моих обновленных вопросов, вам придется выполнять минимальные манипуляции с строками. Я считаю, что это должно работать так, как сейчас. – Reti43

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