2012-02-18 18 views
5

ho qualche codice che assomigli a questo:creare un dizionario Python che contiene coppie chiave-valore specifici da un altro dizionario

d = {'foo': True, 'bar': 42, 'baz': '!'} 

a = {'foo': d['foo'], 'bar': d['bar']} 
b = {'foo': d['foo'], 'baz': d['baz']} 
c = {'bar': d['bar'], 'baz': d['baz']} 

Sicuramente c'è un modo migliore per esprimere questo. Io in realtà leggere i documenti, nella speranza che il metodo di un dizionario copy accetta chiavi da inserire nel nuovo dizionario:

# I'd hoped that something like this would work... 
a = d.copy('foo', 'bar') 
b = d.copy('foo', 'baz') 
c = d.copy('bar', 'baz') 

potrei scrivere una funzione per questo scopo:

copydict = lambda dct, *keys: {key: dct[key] for key in keys} 

a = copydict(d, 'foo', 'bar') 
b = copydict(d, 'foo', 'baz') 
c = copydict(d, 'bar', 'baz') 

C'è una migliore soluzione rispetto a quanto sopra?

+0

Perché non si utilizza un elenco (o un set) per a, b, c? Hai freddo il valore in su quando ne hai bisogno. – maxy

+0

In realtà sto passando 'a',' b' e 'c' alla funzione' urlencode' di Django (che, come 'urllib.urlencode', accetta un dizionario). – davidchambers

+0

@BlaXpirit: dovresti scrivere una risposta contenente solo "No". (attenersi alla dimensione minima con un commento HTML) in modo che tutti possiamo votare follemente. –

risposta

5

Immagino che la funzione nella domanda sia la soluzione migliore.

Certo, qualcuno potrebbe postare qualche codice idiomatico, ma sono sicuro che non funzionerebbe meglio/più veloce. L'iterazione su un elenco e il recupero degli elementi da un tasto per parola è il più veloce possibile.

Un suggerimento è rimuovere la stella dal parametro keys. La decompressione degli argomenti aggiunge costi aggiuntivi non necessari. Non ci dovrebbero essere problemi con il solo passaggio di quelle chiavi come una tupla.

0

Come sottolineato da @BlaXpirit, questa soluzione probabilmente non sta andando essere migliore della tua, in termini di velocità o la leggibilità, ma si poteva fare qualcosa di simile:

>>> from operator import itemgetter 
>>> d = {'foo': True, 'bar': 42, 'baz': '!'} 
>>> keys = ['foo', 'bar'] 
>>> dict(zip(keys, itemgetter(*keys)(d))) 
{'bar': 42, 'foo': True} 
3

L'unico miglioramento vorrei fare è quello di utilizzare una definizione di funzione reale, non un lambda:

def copy_dict(d, *keys): 
    """Make a copy of only the `keys` from dictionary `d`.""" 
    return {key: d[key] for key in keys} 

potrebbe essere utile per affrontare con le chiavi mancanti, ma in Python 2 non è possibile mescolare argomenti chiave opzionali con args * bene, per cui si potrebbe devi passare a un argomento di tupla:

def copy_dict(d, keys, default=None): 
    """Make a copy of only the `keys` from dictionary `d`. 

    Use `default` if a key is missing. 

    """ 
    return {key: d.get(key, default) for key in keys} 
Problemi correlati