10

Getting the error mentioned in the title. The below mentioned functioned is called by another function that is called through a POST api.

Error is on the line below the print statement. Dont know what the error means and why its coming. The same code used to run a week back.

def remove_individual_stops(ordered_parkstop_dict, relevant_data):
    new_ordered_parkstop_dict = ordered_parkstop_dict
    for key, value in ordered_parkstop_dict.items():
        if len(value) == 0:
            for k,v in ordered_parkstop_dict.items():
                if key in v:
                    new_ordered_parkstop_dict.pop(key)
        print (type(ordered_parkstop_dict), ordered_parkstop_dict)
        for k,v in ordered_parkstop_dict.items():
            klist = []
            keylist = []
            if value and v:
                if len(v)==1 and len(value)==1:
                    klist.append(k), keylist.append(key)
                if (keylist == v) and (klist == value and len(value) == 1):
                    new_ordered_parkstop_dict.pop(key)
    return new_ordered_parkstop_dict
blhsing
  • 77,832
  • 6
  • 59
  • 90
python_user
  • 309
  • 1
  • 2
  • 9
  • 2
    you walk through the object and modify it at the same time. – Brown Bear Sep 28 '18 at 06:39
  • [How to delete items from a dictionary while iterating over it?](https://stackoverflow.com/questions/5384914/how-to-delete-items-from-a-dictionary-while-iterating-over-it) I think this is a very relevant answer, besides making a copy of the dictionary, as in the answer. – aspiring1 May 24 '19 at 06:34

1 Answers1

16

You assigned new_ordered_parkstop_dict with a reference of the ordered_parkstop_dict dict, so when you iterate over ordered_parkstop_dict.items() and mutate new_ordered_parkstop_dict by popping it, you mutate ordered_parkstop_dict too, which can't be done since your loop is iterating over ordered_parkstop_dict.

You should assign a copy of ordered_parkstop_dict to new_ordered_parkstop_dict instead. Change:

new_ordered_parkstop_dict = ordered_parkstop_dict

to:

new_ordered_parkstop_dict = ordered_parkstop_dict.copy()
blhsing
  • 77,832
  • 6
  • 59
  • 90
  • 1
    Thanks a lot. The issue is fixed but can you explain why did the error pop up now while the same code was working last week – python_user Sep 28 '18 at 06:56
  • The error does not necessarily occur because you're putting `new_ordered_parkstop_dict.pop(key)` in a conditional block, so with a different input it may or may not trigger the error by satisfying or not satisfying the condition. – blhsing Sep 28 '18 at 06:59
  • Ok thats obvious, but what if i tell you that there is no change with the input as well. The same code is deployed in another server and it runs perfectly for the same input. – python_user Sep 28 '18 at 07:11
  • 2
    That's most likely because the other server is running Python 2.7 or earlier versions, where mutating a dict while iterating over it is allowed. – blhsing Sep 28 '18 at 07:21
  • I had my doubt but didn't check what version of python was runnning. Sir, Thanks a lot for helping out. – python_user Sep 28 '18 at 07:41
  • You don't need any reputation to accept an answer. Try clicking on the grey check mark next to an answer to accept it. :-) – blhsing Sep 28 '18 at 08:06
  • cool, there are very interesting comments above. I migrated my code from python 2.7 to python 3.7. I get the same error with an OrderedDict. Shouldn't I do `deepcopy` instead of `copy`? – alwbtc May 01 '19 at 19:45