2015-10-11 22 views
6

Ciao ho lista come segue che contengono metadati dalle immagini come segue:Formazione di dizionario dalla lista elemento

['Component 1: Y component: Quantization table 0, Sampling factors 1 horiz/1 vert', 
'Component 2: Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert', 
'Component 3: Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert', 
'Compression Type: Progressive, Huffman', 'Content-Length: 14312', 'Content-Type: image/jpeg’] 

Voglio fare un dizionario mediante scissione della lista “:” in lui seguente formato:

{Component 1: {Y component: [Quantization table 0, Sampling factors 1 horiz/1 vert’], 
Component 2: {Cb component: [Quantization table 1, Sampling factors 1 horiz/1 vert]}, 
Component 3: {Cr component: [Quantization table 1, Sampling factors 1 horiz/1 vert]}, 
Compression Type: [Progressive, Huffman],Content-Length: 14312,Content-Type: image/jpeg} 

Attualmente ho scritto del codice che non funziona.

def make_dict(seq): 
res = {} 
if seq[0] is not '': 
    for elt in seq: 
     k, v = elt.split(':') 
     try: 
      res[k].append(v) 
     except KeyError: 
      res[k] = [v] 

print res 

Questo codice non funziona. Ho provato anche altri approcci, ma non sono in grado di ottenere il formato.

+0

Ti aspetti un elenco di dizionario del dizionario come output (come nel tuo primo caso)? –

+0

@akira, si prega di accettare risposte sufficienti con il pulsante segno di spunta. Vale la pena di +2 per te. – kdbanman

risposta

3

È possibile utilizzare una comprensione lista all'interno di una comprensione dict utilizzando collections.OrderedDict:

>>> li=['Component 1: Y component: Quantization table 0, Sampling factors 1 horiz/1 vert', 'Component 2: Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert', 'Component 3: Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert', 'Compression Type: Progressive, Huffman', 'Content-Length: 14312', 'Content-Type: image/jpeg'] 
>>> d=OrderedDict((sub[0],{sub[1]:sub[2:]}) if sub[2:] else (sub[0],sub[1]) for sub in [item.split(':') for item in li]) 
>>> d 
OrderedDict([('Component 1', {' Y component': [' Quantization table 0, Sampling factors 1 horiz/1 vert']}), ('Component 2', {' Cb component': [' Quantization table 1, Sampling factors 1 horiz/1 vert']}), ('Component 3', {' Cr component': [' Quantization table 1, Sampling factors 1 horiz/1 vert']}), ('Compression Type', ' Progressive, Huffman'), ('Content-Length', ' 14312'), ('Content-Type', ' image/jpeg')]) 
>>> 
1

È possibile elegantemente risolvere il problema utilizzando una ricorsione, e un limite di divisione (il secondo argomento di split può essere utilizzato per limitare la count split):

def make_dict(l): 
    d = dict() 
    for elem in l: 
     key, value = elem.split(':', 1) 
     if ':' in value: 
      d[key] = make_dict([value]) 
     else: 
      d[key] = value 
    return d 

e il test sembra soddisfare le vostre aspettative:

>>> l = ['Component 1: Y component: Quantization table 0, Sampling factors 1 horiz/1 vert', 
    'Component 2: Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert', 
    'Component 3: Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert', 
    'Compression Type: Progressive, Huffman', 'Content-Length: 14312', 'Content-Type: image/jpeg'] 
>>> make_dict(l) 
{'Component 1': {' Y component': ' Quantization table 0, Sampling factors 1 horiz/1 vert'}, 
'Component 2': {' Cb component': ' Quantization table 1, Sampling factors 1 horiz/1 vert'}, 
'Component 3': {' Cr component': ' Quantization table 1, Sampling factors 1 horiz/1 vert'}, 
'Compression Type': ' Progressive, Huffman', 
'Content-Length': ' 14312', 
'Content-Type': ' image/jpeg'} 
+0

Grazie mille. È davvero utile – akira

3
l = ['Component 1: Y component: Quantization table 0, Sampling factors 1 horiz/1 vert', 
    'Component 2: Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert', 
    'Component 3: Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert', 
    'Compression Type: Progressive, Huffman', 'Content-Length: 14312', 'Content-Type: image/jpeg'] 

d = {} 

for ele in l: 
    spl = ele.split(":", 2) 
    if len(spl) == 3: 
     k1, k2, v = spl 
     d[k1] = {k2: v.split(",")} 
    else: 
     k,v = spl 
     d[k] = v.split() if "," in v else v 

uscita:

{'Component 1': {' Y component': [' Quantization table 0', 
            ' Sampling factors 1 horiz/1 vert']}, 
'Component 2': {' Cb component': [' Quantization table 1', 
            ' Sampling factors 1 horiz/1 vert']}, 
'Component 3': {' Cr component': [' Quantization table 1', 
            ' Sampling factors 1 horiz/1 vert']}, 
'Compression Type': [' Progressive', ' Huffman'], 
'Content-Length': ' 14312', 
'Content-Type': ' image/jpeg'} 

Per rimuovere lo spazio vuoto si può str.strip fuori:

d = {} 

for ele in l: 
    spl = ele.split(":", 2) 
    if len(spl) == 3: 
     k1, k2, v = spl 
     d[k1] = {k2.strip(): list(map(str.strip,v.split(",")))} 
    else: 
     k,v = spl 
     d[k] = list(map(str.strip, v.split())) if "," in v else v.strip 

uscita:

{'Component 1': {'Y component': ['Quantization table 0', 
           'Sampling factors 1 horiz/1 vert']}, 
'Component 2': {'Cb component': ['Quantization table 1', 
            'Sampling factors 1 horiz/1 vert']}, 
'Component 3': {'Cr component': ['Quantization table 1', 
            'Sampling factors 1 horiz/1 vert']}, 
'Compression Type': ['Progressive', 'Huffman'], 
'Content-Length': '14312', 
'Content-Type': 'image/jpeg'} 

Entrambi i quali in realtà corrisponde l'output previsto.

2

È possibile utilizzare un algoritmo ricorsivo come quello riportato di seguito, se si desidera gestire qualsiasi livello di annidamento dei dizionari. Esempio -

def makedict(elem): 
    if ':' in elem: 
     k,v = map(str.strip, elem.split(':',1)) 
     return {k:makedict(v)} 
    elif ',' in elem: 
     elems = list(map(str.strip, elem.split(','))) #Simply map(...) for Python 2.x 
     return elems 
    return elem 

Se si vuole fare un dizionario di dizionari, si può fare -

d = {} 
for elem in s: 
    d.update(makedict(elem)) 

O se volete un elenco di dizionario dei dictionries chiamare la funzione di cui sopra per ogni elemento nella vostra lista in una lista di comprensione, ad esempio -

result = [makedict(elem) for elem in yourlist] 

Demo per il dizionario dei dizionari -

>>> d = {} 
>>> for elem in s: 
...  d.update(makedict(elem)) 
... 
>>> d 
{'Component 2': {'Cb component': ['Quantization table 1', 'Sampling fac 
>>> import pprint 
>>> pprint.pprint(d) 
{'Component 1': {'Y component': ['Quantization table 0', 
           'Sampling factors 1 horiz/1 vert']}, 
'Component 2': {'Cb component': ['Quantization table 1', 
            'Sampling factors 1 horiz/1 vert']}, 
'Component 3': {'Cr component': ['Quantization table 1', 
            'Sampling factors 1 horiz/1 vert']}, 
'Compression Type': ['Progressive', 'Huffman'], 
'Content-Length': '14312', 
'Content-Type': 'image/jpeg'} 
+1

Ricorsione per gestire qualsiasi livello di annidamento dei dizionari –

+0

Sto indovinando '{Componente 1: {Componente Y:' significherebbe un dict di dict. –

+0

Ovviamente, l'ho fatto sarebbe stato molto semplice cambiare la logica da comp elenco a creare un dizionario di dizionario di dizionari, come aggiornato nell'esempio precedente –

Problemi correlati