python for循环中的某些调用有时每次循环迭代执行两次

时间:2017-01-11 14:21:47

标签: python parsing

我在python 2.7.9中遇到了一个极其严重的问题,涉及以下循环:

for key,value in master_lines.iteritems():
   value = parse_line(value)
   value.insert(0,key)
   if conflict_dict.get(key):
      if len(conflict_dict[key]) > 0:
         conflictcounter += 1
   writer.writerow(value)

具体来说,修改值的两行每次循环迭代执行两次,导致在本节末尾写入的最终值格式错误并且有一堆额外信息。这不是一直发生的 - 一些键/值对完全没有问题处理,然后连续两个或三个将被双重处理,然后接下来的十个将是好的。请注意,writer.writerow(value)调用似乎受此问题的影响,因为输出文件中的损坏是在行级别 - 我不会得到多个同一行的副本。

我应该提一下,这个代码是针对一个庞大的字典(200,000 +条目)运行的,并且在我达到至少第100,000条记录之前,有问题的行为似乎不会开始。行为在运行期间完全一致,只有特定的行受到影响。

我尝试过使用我所知道的所有方法来遍历字典(.iteritems(),. tt。()。onms(),以获取dict中的键,等等) - 并获取无论我使用什么技术,都会产生同样奇怪的结果。

任何想法的人都将不胜感激!

1 个答案:

答案 0 :(得分:0)

python中的字典是一个无序集,您在迭代时会修改字典。试试这个:

>>> a={'b':[1,2,3],'c':[4,5,6]}
>>> for k,v in a.iteritems():
...    v.insert(0,k)
...
>>> print a
{'c':['c',4,5,6], 'b':['b',1,2,3]}

根据实现,处理字典项的顺序不必与将字典项添加到字典的顺序相同。当你在迭代它时更改你的集合时,没有人可以保证订单不会改变,你刚刚处理的元素也可能成为处理"的下一个元素。

如果没有看到您的实际字典内容并完成Python dict的实现,很难猜到会发生什么,但正确的做法是制作副本你的数据。要复制列表项,请使用new_item = old_item[:],如下所示:

>>> a={'b':[1,2,3],'c':[4,5,6]}
>>> a2 = {}
>>> for k,v in a.iteritems():
...    v2 = v[:]
...    v2.insert(0,k)
...    a2[k] = v2
...
>>> print a
{'c':[4,5,6], 'b':[1,2,3]}
>>> print a2
{'c':['c',4,5,6], 'b':['b',1,2,3]}

无论如何,如果你正在处理超过二十万件物品的词典,你可能会做错事。