2010-12-30 13 views
37

Esto es bastante simple, pero me encantaría una forma bonita y pitónica de hacerlo. Básicamente, dado un diccionario, devuelve el subdiccionario que contiene solo aquellas claves que comienzan con una cierta cadena.Cortar un diccionario por claves que comienzan con una cierta cadena

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

Esto es bastante simple de hacer con una función:

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

Pero sin duda hay una más inteligente, la solución más agradable, más fácil de leer? ¿Podría un generador ayudar aquí? (Nunca tengo suficientes oportunidades para usarlos).

+0

no codifican pitón oscura sólo porque es posible. La idea completa de Python es la legibilidad. Si solo necesita potencia oscura, use Perl. – user3181121

+0

También vea http://pythoncentral.io/how-to-slice-custom-objects-classes-in-python/, puede personalizar '__getitem__' en su propio tipo/subclase de dict. – bjd2385

Respuesta

68

¿Qué tal esto:

en Python 2.x:

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

en Python 3.x:

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

No sombree el 'slice' incorporado (aunque casi nadie lo use). –

+0

Esa comprensión dict es deliciosa. Y no tenía idea de que 'slice' fuera un built-in, wtf? – Aphex

+3

@Ignacio: cuando estás en una pequeña función local, realmente no siempre vale la pena preocuparte por pisotear las construcciones internas: hay demasiadas, con nombres demasiado comunes. Mejor solo preocuparse por funciones no triviales (si es eso) y globales. Builtins no son palabras clave, después de todo. –

9

En estilo funcional:

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

+8

En Python, el estilo funcional suele ser justo lo que no desea. –

+13

¿Eh? El enfoque de comprensión dict ciertamente cae dentro de mi definición de "estilo funcional". –

3

En Python 3 uso items() lugar:

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