2010-11-17 17 views
5

[Python 3.1]Python: cómo crear un hash de contenedores anidados

Estoy tratando de crear un hash para un recipiente que pueda haber anidado contenedores en él, con una profundidad desconocida. En todos los niveles de la jerarquía, solo hay tipos incorporados. ¿Cuál es una buena manera de hacer eso?

Por qué lo necesito:

estoy almacenamiento en caché el resultado de unos cálculos en un objeto de salmuera (en el disco). Necesitaría invalidar ese archivo en caché si se llama a la función con diferentes parámetros (esto ocurre con poca frecuencia, así que no voy a guardar más de un archivo en el disco). El hash se usará para comparar los parámetros.

+0

¿Está esperando que estos valores puedan cambiar después de crearlos? – aaronasterling

+0

@aaronsterling: ¿Puedes aclarar por favor? No estoy seguro de responder su pregunta, pero los contenedores o sus contenidos no serán modificados. Sin embargo, debo enfatizar que la persistencia es, por supuesto, necesaria para cualquier invocación futura de este programa Python (en un nuevo proceso). – max

+0

¿Estás de acuerdo con una pequeña posibilidad de que el archivo no sea invalidado por diferentes parámetros de función? Cualquier función hash tendrá una posibilidad de colisión, por lo que está buscando una con una probabilidad mínima de colisión. Solo trato de entender el problema un poco mejor. –

Respuesta

1

Puede serializar los parámetros en algo como JSON, y usar eso para el hash.

+0

Me gusta esta idea. ¿Hay algún problema oculto con eso? Por ejemplo, ¿se rompería en algunas estructuras de anidación complicadas, etc.? – max

+0

No, siempre y cuando se trate de tuplas, listas, dicts, strs y ints, no hay problema. Una advertencia, sin embargo: 'tuple' ==' list' (ya que JavaScript no tiene un concepto 'tuple') –

+2

Creo que usaría' pickle.dumps' en lugar de 'json.dumps'; el encurtido es preciso con tipos y ~ 15% más rápido (los cronometré). –

1

Si todos los contenedores son tuplas, y todos los objetos contenidos son lavables, entonces el contenedor principal debe ser manejable.

+0

Buen punto. Desafortunadamente, entre los contenedores hay diccionarios. – max

+1

Puede convertir diccionarios a una tupla ordenada de tuplas (clave, valor). – Paul

0

Lo haría con serialización json como una cadena [y luego hash esa cadena si es necesario].

from simplejson import dumps 

def hash_data(data): 
    return hash(dumps(data)) 
Cuestiones relacionadas