2012-10-08 29 views
7

Estoy trabajando en algunas secuencias similares a FASTA (no FASTA, pero algo que he definido es similar para algunos PD seleccionados desde el servidor PISCES).Diccionario anidado

Tengo una pregunta. Tengo un pequeño número de secuencias llamadas nCatSeq, para las cuales hay MÚLTIPLES nBasinSeq. Paso por un archivo PDB grande y quiero extraer para cada nCatSeq el correspondiente nBasinSeq sin redundancias en un diccionario. El fragmento de código que hace esto se proporciona a continuación.

nCatSeq=item[1][n]+item[1][n+1]+item[1][n+2]+item[1][n+3] 
nBasinSeq=item[2][n]+item[2][n+1]+item[2][n+2]+item[2][n+3] 
if nCatSeq not in potBasin: 
    potBasin[nCatSeq]=nBasinSeq 
else: 
    if nBasinSeq not in potBasin[nCatSeq]: 
     potBasin[nCatSeq]=potBasin[nCatSeq],nBasinSeq 
    else: 
     pass 

me sale el siguiente como la respuesta para una nCatSeq,

'4241': ((('VUVV', 'DDRV'), 'DDVG'), 'VUVV') 

lo que quiero sin embargo es:

'4241': ('VUVV', 'DDRV', 'DDVG', 'VUVV')

No quiero todos los corchetes adicionales debido al siguiente comando

potBasin[nCatSeq]=potBasin[nCatSeq],nBasinSeq 

(véase más arriba fragmento de código)

¿Hay una manera de hacer esto?

Respuesta

1

Puede agregarlos como tuplas:

if nCatSeq not in potBasin: 
    potBasin[nCatSeq] = (nBasinSeq,) 
else: 
    if nBasinSeq not in potBasin[nCatSeq]: 
     potBasin[nCatSeq] = potBasin[nCatSeq] + (nBasinSeq,) 

De esta manera, en lugar de:

(('VUVV', 'DDRV'), 'DDVG') 
# you will get 
('VUVV', 'DDRV', 'DDVG') # == ('VUVV', 'DDRV')+ ('DDVG',) 
+0

Gracias chicos, Hayden - utilicé su sugerencia y se parece ser justo lo que necesitaba! Muchas gracias. – user1729355

5

El problema es poner una coma para "agregar" un elemento que solo crea una nueva tupla cada vez. Para solucionar esto se utiliza listas y append:

nCatSeq=item[1][n]+item[1][n+1]+item[1][n+2]+item[1][n+3] 
nBasinSeq=item[2][n]+item[2][n+1]+item[2][n+2]+item[2][n+3] 
if nCatSeq not in potBasin: 
    potBasin[nCatSeq]=[nBasinSeq] 
elif nBasinSeq not in potBasin[nCatSeq]: 
     potBasin[nCatSeq].append(nBasinSeq) 

Aún mejor sería que en vez de hacer potBasin un diccionario normal, reemplazarlo con un defaultdict. El código a continuación, se puede simplificar a:

# init stuff 
from collections import defaultdict 
potBasin = defaultdict(list) 

# inside loop 
nCatSeq=item[1][n]+item[1][n+1]+item[1][n+2]+item[1][n+3] 
nBasinSeq=item[2][n]+item[2][n+1]+item[2][n+2]+item[2][n+3] 
potBasin[nCatSeq].append(nBasinSeq) 
0

Su pregunta se reduce a aplanar un anidado lista y eliminación de entradas redundantes:

def flatten(nested, answer=None): 
    if answer is None: 
     answer = [] 
    if nested == []: 
     return answer 
    else: 
     n = nested[0] 
     if is instance(n, tuple): 
      return flatten(nested[1:], nested(n[0], answer)) 
     else: 
      return flatten(nested[1:], answer+n[0]) 

Así, con su diccionario anidada:

for k in nested_dict: 
    nested_dict[k] = tuple(flatten(nested_dict[k])) 

si desea eliminar las entradas duplicadas:

for k in nested_dict: 
    nested_dict[k] = tuple(set(flatten(nested_dict[k]))) 

espero que esto ayude