recorrer - Usar regex para transformar datos en un diccionario en Python
lista de diccionarios python (4)
Tengo un conjunto de datos con secuenciación formateada FASTA , básicamente así:
>pc284
ATCGCGACTCGAC
>pc293
ACCCGACCTCAGC
Quiero utilizar cada etiqueta como clave en el diccionario y almacenar el gen como un valor.
Este es el código que tengo, pero realmente no está haciendo nada:
import re
fileData = open(''d.fasta'', ''r'')
myDict = dict()
for line in fileData:
match = re.search(''(/>)(/w+)(/r)(/w+)'', line)
if match:
gene = match.group(3)
myDict[gene[0]] = gene[1]
print myDict
A menos que su archivo sea demasiado grande para caber en la memoria (que supongo que no es así), todo es tan simple como
with open(''d.fasta'') as fp:
myDict = dict(re.findall(r''(?m)^>(/w+)/s+^(/S+)'', fp.read()))
Dos errores que veo:
Tu expresión regular probablemente sea incorrecta. Es poco probable que su entrada FASTA realmente contenga un retorno de carro desnudo ( /r
), por lo que su expresión regular no coincidirá con nada. De ahí la if match:
prueba siempre es falsa, por lo que no ocurre nada.
Además, al procesar cada coincidencia: está agregando el primer carácter del gene
(que es el espacio en blanco) como una clave y el segundo carácter como el valor.
Probablemente quisiste usar los grupos 2 y 4 respectivamente:
myDict[match.group(2)] = match.group(4)
no uses una expresión regular para esto ...
class FASTA(object):
def __init__(self,data):
self.data = data.strip().splitlines()
self.desc = self.data[0]
self.sequence = "".join(self.data[1:]).replace(" ","")#get rid of spaces
def GetCodons(self):
return [self.sequence[i:i+3] for i in range(0,len(self.sequence),3)]
def __str__(self):
return "DESC:''%s''/nSEQ:''%s''"%(self.desc,self.sequence)
with open("data.fasta") as f:
data = f.read()
parts = data.split(">")
for p in parts[1:]:
f= FASTA(p)
print f
print f.GetCodons()
no es una clase de caracteres válida, creo que en realidad querías usar /s
. Puede reducir los grupos si no los usa tampoco.
Pero, sobre todo, debes extraer tus grupos correctamente:
match = re.search(r''>(/w+)/s+(/w+)'', line)
if match:
tag, gene = match.groups()
myDict[tag] = gene
Al crear solo dos grupos de captura, podemos simplemente extraer esos dos con .groups()
y asignarlos directamente a dos variables, tag
y gene
.
Sin embargo, leer en el formato FASTA parece indicar que se trata de un formato multilínea con la etiqueta en una línea, los datos del gen en varias líneas después de eso. En ese caso, tu /r
estaba destinado a coincidir con la nueva línea. Esto no funcionará cuando lea el archivo una línea a la vez.
Sería mucho más simple leer ese formato sin expresiones regulares como esta:
myDict = {}
with open(''d.fasta'', ''rU'') as fileData:
tag = None
for line in fileData:
line = line.strip()
if not line:
continue
if line[0] == ''>'':
tag = line[1:]
myDict[tag] = ''''
else:
assert tag is not None, ''Invalid format, found gene without tag''
myDict[tag] += line
print myDict
Esto lee el archivo línea por línea, detecta etiquetas basadas en el carácter inicial >
y luego lee múltiples líneas de información genética que se recopilan en su diccionario con la etiqueta de lectura más reciente.
Tenga en cuenta el modo rU
; abrimos el archivo utilizando el modo de nuevas líneas universales de Python , para manejar cualquier convención de nueva línea que se haya utilizado para crear el archivo.
Por último, si bien no menos importante; echa un vistazo al proyecto BioPy ; su módulo Bio.SeqIO
maneja FASTA más muchos otros formatos perfectamente.