Заполнение словаря несколькими строками в одну строку - PullRequest
1 голос
/ 24 мая 2019

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

>piece_1 
Lorem ipsum dolor sit amet
consectetur adipiscing elit. Nam a pellentesque mi. 
>piece_2 
Integer dignissim ultrices eros a consequat. Praesent vestibulum
>piece_3 
Morbi eget sollicitudin mauris. Nunc varius felis 
vitae dui congue hendrerit. Nam semper venenatis auctor.  
Suspendisse potenti. Suspendisse facilisis velit vel convallis 
fringilla. Duis condimentum auctor mauris eu lobortis. 

Я хочу создать из текста выше словарь, содержащий все отдельные фрагменты текста с ключами >piece_1 и т. Д.

Пока мне удалось заполнить словарь всеми ключами, но я не могу сказать, как извлечь текст из файла.

f = open('Output.txt', 'r')
mydict = dict()

for index, line in enumerate(f):
    if line[:1]=='>':
        mydict[index] = line #instead, the key should be line with the value being the relative text.
        print(line, end='')

Ответы [ 4 ]

3 голосов
/ 24 мая 2019

Я предлагаю использовать Biopython , это будет более надежным и лаконичным, чем написание собственного решения:

>>> from Bio import SeqIO
>>> d = SeqIO.to_dict(SeqIO.parse('input.fa', 'fasta'))

Для ваших данных:

>>> d['piece_1']
SeqRecord(seq=Seq('Loremipsumdolorsitametconsecteturadipiscingelit.Namape...mi.', SingleLetterAlphabet()), id='piece_1', name='piece_1', description='piece_1', dbxrefs=[])
>>> str(d['piece_1'].seq)
'Loremipsumdolorsitametconsecteturadipiscingelit.Namapellentesquemi.'
1 голос
/ 24 мая 2019

Это один подход, использующий простую итерацию.

Ex:

result = []
with open(filename) as infile:
    for line in infile:
        if line.startswith(">"):             #Check if line starts with '>'
            result.append([line, []])        #Create new list with format --> [key, [list of corresponding text]]
        else:
            result[-1][1].append(line)       #Append text to previously found key. 

mydict ={k: "".join(v) for k, v in result}   #Form required dictionary. 
print(mydict)

Выход:

{'>piece_1 \n': 'Lorem ipsum dolor sit amet\nconsectetur adipiscing elit. Nam a pellentesque mi. \n',
 '>piece_2 \n': 'Integer dignissim ultrices eros a consequat. Praesent vestibulum\n',
 '>piece_3 \n': 'Morbi eget sollicitudin mauris. Nunc varius felis \nvitae dui congue hendrerit. Nam semper venenatis auctor.  \nSuspendisse potenti. Suspendisse facilisis velit vel convallis \nfringilla. Duis condimentum auctor mauris eu lobortis. '}
1 голос
/ 24 мая 2019

вы могли бы это collections.defaultdict

from collections import defaultdict
result = defaultdict(list)
index = None
for line in text:
    if line.startswith(">"):
        index = line[1:]
    else:
        result[index].append(line)
{
    "piece_1 ": [
        "Lorem ipsum dolor sit amet",
        "consectetur adipiscing elit. Nam a pellentesque mi. ",
    ],
    "piece_2 ": [
        "Integer dignissim ultrices eros a consequat. Praesent vestibulum"
    ],
    "piece_3 ": [
        "Morbi eget sollicitudin mauris. Nunc varius felis ",
        "vitae dui congue hendrerit. Nam semper venenatis auctor.  ",
        "Suspendisse potenti. Suspendisse facilisis velit vel convallis ",
        "fringilla. Duis condimentum auctor mauris eu lobortis.",
    ],
}
0 голосов
/ 24 мая 2019

Вот еще одна компактная возможность с использованием списочных и вихревых представлений:

with open('Output.txt', 'r') as f:
    s = f.read()
result = {k.strip(): v for k, v in [part.split('\n', maxsplit=1)
                                    for part in s.split('>')[1:]] }

В понимании внутреннего списка: 0-й элемент списка, который возвращает s.split('>'), является пустой строкой, поэтому мы игнорируем ее. maxsplit=1 при последующем разбиении на \n предотвращает разбиение текста более чем на 2 части.

...