2013-03-20 10 views
5

Desidero applicare una funzione ai valori di dict in posizione nel dict (come map in un'impostazione di programmazione funzionale).Modifica valori dict inplace

Diciamo che ho questo dict:

d = { 'a':2, 'b':3 } 

voglio applicare la funzione divide by 2.0 a tutti i valori del dizionario, che porta a:

d = { 'a':1., 'b':1.5 } 

Qual è il modo più semplice per Fai quello?

Io uso Python 3.

Modifica: Un one-liner sarebbe bello. Il divide by 2 è solo un esempio, ho bisogno che la funzione sia un parametro.

risposta

6

Si possono trovare moltiplicano è ancora più veloce di dividendo

d2 = {k: v * 0.5 for k, v in d.items()} 

Per una versione interna

d.update((k, v * 0.5) for k,v in d.items()) 

Per il caso generale

def f(x) 
    """Divide the parameter by 2""" 
    return x/2.0 

d2 = {k: f(v) for k, v in d.items()} 
+1

Pensi davvero che moltiplicare sarà molto più veloce della divisione? Forse in PyPy, dove tutti i costi, ma l'aritmetica sono ridotti al punto in cui fa la differenza, ma in CPython, scommetto che non puoi nemmeno rilevare la differenza ... – abarnert

+0

Inoltre, penso che passare la comprensione del Dtc in questo caso 'd2' invece di un'espressione generatore che genera tuple potrebbe essere più leggibile in questo caso (anche se crea" sprecamente "un nuovo dizionario). – abarnert

+0

Come nota a margine, in realtà non mi piacciono le interpretazioni in dict nel codice python3.x per due motivi principali - ** 1) ** Il tuo codice non è retrocompatibile con python2.6, ** 2) ** la comprensione del ditt sembra un po 'troppo simile alle comprensioni dell'insieme. (Inoltre non mi piacciono i letterali impostati per lo stesso motivo) – mgilson

3
>>> d = { 'a': 2, 'b': 3 } 
>>> {k: v/2.0 for k, v in d.items()} 
{'a': 1.0, 'b': 1.5} 
+3

questo modo si crea un nuovo diritto dizionario? Quindi con un enorme "dict", richiederebbe un uso intensivo delle risorse. C'è un modo per modificare semplicemente i valori senza perdere il vantaggio di avere il 'dict 'già costruito? (quindi il 'inplace' nella mia domanda) – Mic

+0

@Mic Non preoccuparti delle prestazioni a meno che non ci sia un problema di prestazioni (e non sto dicendo che non c'è, ma * giustifichi * l'asserzione) - o mantenendo lo stesso oggetto è richiesto per altri motivi semantici. Detto questo, sono completamente d'accordo con jamylak: "inplace" (mutante) e "functional" (immutable) sono abbastanza ortogonali, a seconda di dove viene tracciata la linea. –

+0

@Mic Vero ma quando ho sentito la parola "funzionale" non pensavo che me lo avresti detto. – jamylak

15

è possibile scorrere le chiavi e li aggiorna:

for key, value in d.items(): 
    d[key] = value/2 
+0

Anche questo potrebbe essere un 1-liner (se si imbroglia un po ') - 'per chiave, valore in d.items(): d [chiave] = valore/2' – mgilson

+1

Non penso esplicitamente usando' articoli 'e' value' in questo caso sta salvando qualsiasi cosa nella leggibilità (o performance, se questo è importante); La risposta di Ishpeck sembra più semplice (ad eccezione del nome della variabile migliore). – abarnert

+0

@mgilson: Se Guido lo suggerisce, non conta come barare, giusto? (Naturalmente lo suggerisce come "Se devi averlo su una riga ...") – abarnert

8

dovrebbe funzionare per voi:

>>> d = {'a':2.0, 'b':3.0} 
>>> for x in d: 
...  d[x]/=2 
... 
>>> d 
{'a': 1.0, 'b': 1.5}