2012-04-11 11 views
9

he obj como estopitón: el diccionario de tamaño cambiado durante la iteración

{hello: 'world', "foo.0.bar": v1, "foo.0.name": v2, "foo.1.bar": v3} 

Se debe ampliar a

{ hello: 'world', foo: [{'bar': v1, 'name': v2}, {bar: v3}]} 

escribí código de abajo, splite por '.', retire la llave de edad, añadir nueva clave si contiene '.', pero dijo RuntimeError: dictionary changed size during iteration

def expand(obj): 
    for k in obj.keys(): 
     expandField(obj, k, v) 

def expandField(obj, f, v): 
    parts = f.split('.') 
    if(len(parts) == 1): 
     return 
    del obj[f] 
    for i in xrange(0, len(parts) - 1): 
     f = parts[i] 
     currobj = obj.get(f) 
     if (currobj == None): 
      nextf = parts[i + 1] 
      currobj = obj[f] = re.match(r'\d+', nextf) and [] or {} 
     obj = currobj 
    obj[len(parts) - 1] = v 

para k, v en obj.iteritems():

RuntimeError: diccionario de tamaño cambiado durante la iteración

+1

¿Y cuál es tu pregunta? ¿El error no está claro? –

+8

** Busque antes de publicar ** - http://stackoverflow.com/search?q=RuntimeError%3A+dictionary+changed+size+during+iteration –

+0

posible duplicado de [¿Cómo solucionar este error de python? RuntimeError: el tamaño del diccionario cambió durante la iteración] (http://stackoverflow.com/questions/2844837/how-to-fix-this-python-error-runtimeerror-dictionary-changed-size-during-itera) –

Respuesta

20

Al igual que el mensaje dice: ha cambiado el número de entradas en obj interior de expandField(), mientras que en el medio de haciendo un bucle sobre estas entradas en expandir.

Puede intentar en su lugar crear un nuevo diccionario de la forma que desee, o de alguna manera registrar los cambios que desea hacer, y luego hacerlos DESPUÉS de que el bucle esté hecho.

+3

Sí, un nuevo diccionario es el camino a seguir. Esto también simplifica la recursión. –

3

Tuve un problema similar con el deseo de cambiar la estructura del diccionario (eliminar/agregar) los dicts dentro de otros dicts.

Para mi situación, creé una copia profunda del dict. Con una copia profunda de mi dict, pude iterar y eliminar claves según sea necesario. Deepcopy - PythonDoc

A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

Hope this helps!

6

Es posible que desee copiar las llaves en una lista y iterar sobre su dict usando este último, por ejemplo:

def expand(obj): 
    keys = obj.keys() 
    for k in keys: 
     expandField(obj, k, v) 

que vamos a analizar si el comportamiento resultante se adapte a sus resultados esperados.

Cuestiones relacionadas