2010-12-30 16 views
37

Questo è piuttosto semplice, ma mi piacerebbe un modo carino e pitonioso di farlo. Fondamentalmente, dato un dizionario, restituire il sottodictionary che contiene solo quelle chiavi che iniziano con una determinata stringa.Affettare un dizionario con i tasti che iniziano con una certa stringa

» d = {'Apple': 1, 'Banana': 9, 'Carrot': 6, 'Baboon': 3, 'Duck': 8, 'Baby': 2} 
» print slice(d, 'Ba') 
{'Banana': 9, 'Baby': 2, 'Baboon': 3} 

Questo è abbastanza semplice da fare con una funzione:

def slice(sourcedict, string): 
    newdict = {} 
    for key in sourcedict.keys(): 
     if key.startswith(string): 
      newdict[key] = sourcedict[key] 
    return newdict 

Ma sicuramente c'è una, più intelligente, la soluzione più leggibile più bello? Potrebbe un generatore aiutare qui? (Non ho mai abbastanza opportunità per usarli).

+0

non fare il codice python oscura solo perché è possibile. L'intera idea di Python è la leggibilità. Se hai solo bisogno di potere oscuro, usa Perl. – user3181121

+0

Vedere anche http://pythoncentral.io/how-to-slice-custom-objects-classes-in-python/, è possibile personalizzare '__getitem__' nel proprio tipo/sottoclasse di dict. – bjd2385

risposta

68

ne dite di questo:

in Python 2.x:

def slicedict(d, s): 
    return {k:v for k,v in d.iteritems() if k.startswith(s)} 

in Python 3.x:

def slicedict(d, s): 
    return {k:v for k,v in d.items() if k.startswith(s)} 
+3

Non ombreggiare il 'slice' integrato (anche se quasi nessuno lo usa). –

+0

Questa comprensione del ditt è deliziosa. E non avevo idea che 'slice' fosse un built-in, wtf? – Aphex

+3

@Ignacio: Quando sei in una piccola funzione locale, non vale sempre la pena preoccuparsi di intervenire sui builtin: ce ne sono troppi, con nomi troppo comuni. Meglio solo preoccuparsi di ciò per funzioni non banali (se questo) e globali. I costruttori non sono parole chiave, dopotutto. –

9

In stile funzionale:

dict(filter(lambda item: item[0].startswith(string),sourcedict.iteritems()))

+8

In Python, lo stile funzionale è solitamente quello che non vuoi. –

+13

Eh? L'approccio di dict-comprensione rientra certamente nella mia definizione di "stile funzionale". –

3

In Python 3 uso items() invece:

def slicedict(d, s): 
    return {k:v for k,v in d.items() if k.startswith(s)} 
Problemi correlati