4

I realize that mutating dictionaries while looping over them can cause runtime errors, but I know there are proper ways to do it and I can't figure out which are acceptable and which aren't. Console testing them doesn't help because they MAY produce runtime errors, I'm not sure if I'm getting it correct or just getting lucky.

Say I have an attribute, status, that is a dictionary of statuses:

self.status = {"overall": False, "started":False,
               "ready":False, "awakeQueried":False,
               "allQueried":False}

These change to various Trues or Falses throughout running. I have a function that handles a failure and wants to set all of them to False. What's the elegant way? So far I have this working, but I'm not sure if I'll run into a runtime error at some point:

self.status = {key:False for key in self.status}

Can I do that? I'm not sure of the low-level functioning, here. I'm not making a copy with .items() or the like. I'm overwriting the dictionary but it should process the right side first, but it's a comprehension, so I'm not sure if it completes the entire comprehension first before overwriting self.status. Does it store a kind of copy in memory while it comprehends the new dict and then sets it or does it loop through the dict comprehending and setting items after each iteration (which is where I think problems would arise)?

linus72982
  • 1,418
  • 2
  • 16
  • 31

2 Answers2

3

That will work for precisely the reason you describe: the right hand side comprehension creates a new dictionary and completes before self.status is set to it.

Vaibhav Sagar
  • 2,208
  • 15
  • 21
1

Yes that will work. In Python the variables are references, so you create a new dictionary on the right hand side and then assign it in a single step to self.status leaving no room for runtime errors of reading and writing into a single dict.

mirosval
  • 6,671
  • 3
  • 32
  • 46