在迭代期间修改字典

时间:2015-08-04 16:42:28

标签: python dictionary

我正在循环sorteddict。有时在循环期间,我需要使用不同的“键”重新插入相同的对象(总是更大,因此总是出现在循环的后面)并且仍然在循环期间获得此对象。

原因是:dict使用“cost”作为键来存储对象。我正在尝试选择n个对象,最大限度地降低总成本。但是,根据以前选择的对象,对象的成本可能会增加。

通常,在迭代期间尝试修改dict的人的建议是使用副本。但是在这里我看不出这将如何应用,我不想修改字典,我正在尝试获取对象的顺序。

我试过这样的事情:

from blist import sorteddict

d = sorteddict({ 0:'A', 1:'B', 2:'C', 5:'D'})
selection = []

for cost in d:
    # If 'A' is in selection, the cost of 'B' becomes 4
    new_cost = 4 if 'A' in selection and d[cost]=='B' else cost

    if new_cost == cost:
        selection.append(d[cost])
    else:
        d[new_cost] = d[cost]

    print(d[cost])

(在这个非常简单的例子中,'A'和'B'简化了对象成本之间的关系) 我试图得到:

A
B
C
B
D

而且:selection = ['A', 'C', 'B', 'D']。但是我遇到了运行时错误:

Traceback (most recent call last):

  File "<ipython-input-130-a45532380c1c>", line 1, in <module>
    for k in d:

  File "/local1/public/anaconda3/lib/python3.4/site-packages/blist/_sortedlist.py", line 427, in __iter__
    raise RuntimeError('Set changed size during iteration')

RuntimeError: Set changed size during iteration

是否有某种数据结构允许这种情况(或更好的方法来解决这个问题)?

2 个答案:

答案 0 :(得分:1)

你无法为正在迭代的字典添加键,即改变字典的大小,你可以使用.keys来避免错误,而不需要制作字典的完整副本:

for cost in list(d.keys()):

答案 1 :(得分:0)

找到一种方法,使用sortedlist来存储密钥(sorteddictsortedset无法在循环中进行编辑,但sortedlist可以,不确定原因)。

In [5]: from blist import sorteddict, sortedlist
   ...: 
   ...: d = sorteddict({ 0:'A', 1:'B', 2:'C', 5:'D'})
   ...: keys = sortedlist(d.keys())
   ...: selection = []
   ...: 
   ...: for cost in keys:
   ...:     # If 'A' is in selection, the cost of 'B' becomes 4
   ...:     new_cost = 4 if 'A' in selection and d[cost]=='B' else cost
   ...:     
   ...:     if new_cost == cost:
   ...:         selection.append(d[cost])
   ...:     else:
   ...:         d[new_cost] = d[cost]
   ...:         keys.add(new_cost)
   ...: 
   ...: 
   ...: print('selection =',selection)

selection = ['A', 'C', 'B', 'D']

我想现在,可以使用简单的dict代替sorteddict。还是有点调整,所以如果有人找到更令人满意的答案,我会打开问题。