在做對員工信息增刪改查這個作業時,有一個需求是通過用戶輸入的id刪除用戶信息。我把用戶信息從文件提取出來儲存在了字典里,其中key是用戶id,value是用戶的其他信息。在循環字典的時候,當用戶id和字典里的key相等時,會刪除這條信息,當時刪除時報錯RuntimeError: dictionary changed size during iteration。
for key in staff_info: if user_id == key: print(key) staff_info.pop(key) id_exist = True
參考:https://www.python.org/dev/peps/pep-0234/#dictionary-iterators
在官網看到解釋:
Dictionaries implement a tp_iter slot that returns an efficient iterator that iterates over the keys of the dictionary. During such an iteration, the dictionary should not be modified, except that setting the value for an existing key is allowed (deletions or additions are not, nor is the update() method). This means that we can write
for k in dict: ...
which is equivalent to, but much faster than
for k in dict.keys(): ...
as long as the restriction on modifications to the dictionary (either by the loop or by another thread) are not violated.
意思是多字典在被循環的時候不能被循環刪除和更新,除了給一個已經存在的key設置value。還說道 for kin dict: ...和for k in dict.keys(): ...效果是一樣的,但是前者速度更快。
那就來試驗一下:
a = {'a': 1, 'b': 0, 'c': 1, 'd': 0} for key in a: print(key, a[key]) for key in a.keys(): print(key, a[key]) # 兩個循環效果一樣 print(a.keys()) # dict_keys(['a', 'b', 'c', 'd']) print(a) # {'a': 1, 'b': 0, 'c': 1, 'd': 0}
除了a.keys是dict_keys類型,它們的效果是一樣的。
那么解決方案就出來了,轉換成列表形式就OK了。
for key in list(staff_info.keys()): if user_id == key: print(key) staff_info.pop(key) id_exist = True