我有一个要迭代并更改其值的字典,但是我认为更改长度可能会导致错误,有什么好的方法吗?
示例:
d = {'a':'orange','b':'pineapple','c':'dragonfruit'}
rating = {'orange':3, 'pineapple':4, 'dragonfruit':4.5, 'apple':3, 'pear': 3.5}
for key, value in d.items():
if some conditions met:
del d['a'] or d['e']='apple' # (or is not operator, i mean literally one of the operation add or delete item...)
例如:
for key, value in d.items():
if rating[value]<4:
del d[key]
或
d = {'a':['orange'],'b':['pineapple','peach'],'c':['dragonfruit']}
rating = {'orange':3, 'pineapple':4, 'dragonfruit':4.5, 'apple':3, 'pear': 3.5, 'peach': 5}
for key, value in d.items():
rating_sum = sum([ rating[v] for v in value])
if rating_sum > 8 and len(value)>1:
d['e'] = d[key].pop(-1)
可能不是最好的例子...意味着字典的长度在循环中改变。
答案 0 :(得分:5)
在迭代字典时不要添加或删除键。另外,请勿遮挡内置dict
。
您可以在所有条件下使用字典理解:
d = {k: v for k, v in d.items() if \
not (conditions and \
((k == 'a') or ((k, v) == ('e', 'apple'))))}
我假设您的conditions
是k
和v
的函数,否则您应该在字典理解之外计算和应用此测试。
但是这可能会有点混乱,因此将逻辑分离为一个函数没有什么害处:
def keep_pair(k, v):
if conditions:
if (k == 'a') or ((k, v) == ('e', 'apple')):
return False
return True
d = {k, v for k, v in d.items() if keep_pair(k, v)}
答案 1 :(得分:0)
您可以将dict复制到某个临时dict变量,然后遍历该临时dict,但对原始dict进行更改。
temp = dict.copy()
for key, value in temp.items():
if some conditions met:
del dict['a'] or dict['e']='apple'
答案 2 :(得分:0)
不要。这不是不可能的,但是在大多数情况下,没有理由不创建新字典并重新分配名称,这样更易于读写。
d = <SOME-DICT>
# filter d with dict comprehension, reassign the name d
d = {k:v for k,v in d.items() if <FILTERING-CONDITION>}
一些演示::
>>> d = {'a':'orange','b':'pineapple','c':'dragonfruit'}
>>> {k:v for k,v in d.items() if v != 'pineapple'}
{'a': 'orange', 'c': 'dragonfruit'}
>>> {k:v for k,v in d.items() if not (k == 'd' and v == 'dragonfruit')}
{'a': 'orange', 'b': 'pineapple', 'c': 'dragonfruit'}
>>> {k:v for k,v in d.items() if not (k == 'c' and v == 'dragonfruit')}
{'a': 'orange', 'b': 'pineapple'}
>>> {k:v for k,v in d.items() if not (k == 'a' or (k == 'e' and v == 'pineapple'))}
{'b': 'pineapple', 'c': 'dragonfruit'}