views:

50

answers:

2

In the below code d_arr is an array of dictionaries

 def process_data(d_arr):
    flag2 = 0
    for dictionaries in d_arr:  
      for k in dictionaries:
        if ( k == "*TYPE" ):
          """ Here we determine the type """
          if (dictionaries[k].lower() == "name"):
            dictionaries.update({"type" : 0})
            func = name(dictionaries)
            continue
          elif (dictionaries[k].lower() == "ma"):
            dictionaries.update({"type" : 1})
            func = DCC(dictionaries)
            logging.debug(type(func))
           continue      

When the above is done i get an error saying

               for k in dictionaries:
            RuntimeError: dictionary changed size during iteration
           2010-08-02 05:26:44,167 DEBUG Returning

Is this forbidden to do something like this

+3  A: 

That error is pretty informative; you can't change the size of a dictionary you are currently iterating over.

The solution is to get the keys all at once and iterate over them:

# Do this
for k in dictionaries.keys():

# Not this
for k in dictionaries:
Triptych
Thanks..........
Hulk
+3  A: 

It is, indeed, forbidden. Moreover, you don't really need a loop over all keys here, given that the weirdly named dictionaries appears to be a single dict; rather than the for k in dictionaries: (or the workable for k in dictionaries.keys() that @Triptych's answer suggests), you could use...:

    tp = dictionaries.get('*TYPE')
    if tp is not None:
      """ Here we determine the type """
      if tp.lower() == 'name':
        dictionaries.update({"type" : 0})
        func = name(dictionaries)
      elif tp.lower() == "ma":
        dictionaries.update({"type" : 1})
        func = DCC(dictionaries)
        logging.debug(type(func))

This is going to be much faster if dictionaries has any considerable length, for you're reaching directly for the one entry you care about, rather than looping over all entries to check each of them for the purpose of seeing if it is the one you care about.

Even if you've chosen to omit part of your code, so that after this start the loop on dictionaries is still needed, I think my suggestion is still preferable because it lets you get any alteration to dictionaries done and over with (assuming of course that you don't keep altering it in the hypothetical part of your code I think you may have chosen to omit;-).

Alex Martelli
Thanks very useful tip.
Hulk
Man how do you find the time? You, like, actually read all the code.
Triptych