2011-02-01 26 views
7

Ho la seguente funzione:mappa Marca() restituisce un dizionario

def heading_positions(self): 
    return map(
      lambda h: 
       {'{t}.{c}'.format(t=h.table_name,c=h.column_name) : h.position }, 
       self.heading_set.all() 
      ) 

Mi dà output come questo:

[{'customer.customer_number': 0L}, {'customer.name': 2L}, ... ] 

io preferirei un solo dizionario come questo:

{'customer.customer_number': 0L, 'customer.name': 2L, ... 

C'è un modo per rendere map (o qualcosa di simile) restituire solo un singolo dizionario invece di una matrice di dizione Ariete?

risposta

7

Perché utilizzare map() allora?

dict(
    ('{t}.{c}'.format(t=h.table_name, c=h.column_name), h.position) 
    for h in self.heading_set.all() 
    ) 

dovrebbe funzionare.

+3

Oppure '{'{t}. {C}'. Format (...): h.position per h in self.heading_set.all()}' nelle versioni più recenti (quelle con comprensione di dict). – delnan

+1

La comprensione del Dict appare in 2.7/3.1. –

2
return dict(('{t}.{c}'.format(t=h.table_name, c=h.column_name), h.position) 
      for h in self.heading_set.all()) 
1

Come altre risposte mostrano, è possibile utilizzare le comprensibilità dict().

Ma, come una curiosità, forse, è anche possibile utilizzare reduce

EDIT: Come il commento dice, dict() è più facile in questo caso. Ma, solo per amor di teoria, quello che volevo dire è che è possibile risolvere utilizzando blocchi solo funzionali (senza comprensioni del dizionario magici del pitone):

def union(d1,d2): 
    result = {} 
    result.update(d1) 
    result.update(d2) 
    return result 

Poi:

reduce(union, sequence_of_dictionaries, {}) 

In alternativa, meno pulito ma più efficiente, utilizzando una versione alternativa di dict.update che restituisce il primo argomento:

def update2(d1, d2): 
    dict.update(d1, d2) 
    return d1 

O anche:

update2 = lambda d1,d2: (d1, d1.update(d2))[0] 

Poi:

reduce(update2, sequence_of_dictionaries, {}) 

Dove in questo caso sarebbe sequence_of_dictionaries:

[{'{t}.{c}'.format(t=h.table_name, c=h.column_name) : h.position} 
for h in self.heading_set.all()] 
+0

...... Per cosa? – eumiro

+1

Non importa, dict() con una lista di comprensione è una soluzione più veloce in questo caso. Ma, in teoria, vuoi un fold over union e un vuoto dict, che era quello che stavo puntando ... – sinelaw

+0

Se la tua risposta è sbagliata, cancellala o risolvila. Se è corretto, includi un esempio di come farlo. – agf

6

Sì. Il problema di base è che non si crea un dizionario da una singola voce dict s, ma da una sequenza di sequenze di lunghezza due (key, value).

Così, piuttosto che creare un unico ingresso indipendente dict con la funzione, creare una tupla e quindi è possibile utilizzare il dict() costruttore:

dict(map(lambda h: ('{t}.{c}'.format(t=h.table_name, c=h.column_name), h.position), 
     self.heading_set.all())) 

O direttamente utilizzare un generatore o di lista all'interno del costruttore dict :

dict(('{t}.{c}'.format(t=h.table_name, c=h.column_name), h.position) 
    for h in self.heading_set.all()) 

Oppure, sulle ultime versioni (2.7, 3.1) una comprensione del dizionario direttamente:

{'{t}.{c}'.format(t=h.table_name : c=h.column_name), h.position) 
    for h in self.heading_set.all()} 
Problemi correlati