2011-11-03 106 views
0

我想找到在python中的键中迭代值的最佳方法。在python中通过键迭代字典多个值

我有与结构文件:

17 KEY1

18 KEY1

45 KEY2

78 KEY2

87 KEY2

900 KEY3

92 KEY4

所以我需要第二列作为关键(无重复)和链接设定为对应于它这个密钥的所有值(第一列)。

'KEY1':[ '17', '18']

'KEY2':[ '45', '78', '87']

'KEY3':[” 900 ']

'KEY4':' 92' ]

到现在为止我做不使用词典:

for line in file: 

      value, key = line.strip().split(None,1) 

,然后我可以把它放进字典,

diction.setdefault(key, []).append(value) 

所以之后,我有一个很好的解释,因为我需要的。

但之后,我必须重读文件以进行更改。可以在键(对)(添加/删除)中或仅在值(添加/删除)中发生更改如何检查迭代键是否按值进行更改?

UPD ***: 钥匙检查或多或少是明确的:

if diction[key]: 

但如何遍历值的键里面? 我需要找到差异,然后从字典中添加\删除此值\ pair(如果键的最后一个值)?

我想这可以用iteritem()\ itervalues()或smthng来完成,但我并不熟悉它。

谢谢你的帮助。

UPD ***

谢谢@乔尔。最后我用了3张支票。首先是添加任何按键:

set_old_dict = set(new_old.keys()) 
set_new_dict = set(new_dict.keys()) 
intersect = set_new_dict.intersection(set_old_dict) 



def added(self): 
    return set_new_dict - intersect 
    def removed(self): 
    return set_old_dict - intersect 

然后,如果我不明白或已经处理这个情况下,我会用你的函数:

def comp(old_dict, new_dict): 
    for key, old_val in old_dict.items(): 
     new_val = new_dict[key] 
     print 'evolutions for', key 
     print 'new content:', [x for x in new_val if x not in old_val] 
     print 'removed content:', [x for x in old_val if x not in new_val] 
+0

每次更新文件时,重新构建整个词典对您来说很重要吗? – nmichaels

+1

实际上,请不要**使用'if diction [key]:',使用'if key in diction:'。 – hochl

+0

如果我将'18 key1'这一行更改为'17 key1',那么'diction ['key1']'是否包含'17'或两个副本?订单是否重要?如果该文件首先是这样的呢? –

回答

1

我的建议是,如果你要重新读取输入文件,你也可以重新创建你的字典,但这取决于字典创建所需的时间。按照您的要求,也许分析文件中的差异并更新字典会更快。

您可以看看difflib模块,然后分析差异。基于此,可以在字典中删除删除,必要时添加添加。

不幸的是,我敢打赌你的输出会很难:这意味着人类可读,而不是机器可读,所以可能会有更好的答案。


编辑,如果你想保留之间的两个文件版本的变化轨迹,写在你的评论,你可以比较的字典。对于钥匙,你已经有了需要的东西。

现在,更新的值:如果你确信你的价值观永远是字符串列表,那么你可以做完全一样的事情,作为比较字典键:

>>> def comp(old_dict, new_dict): 
...  for key, old_val in old_dict.items(): 
...   new_val = new_dict[key] # warning: to be used on keys in both dict 
...   print 'evolutions for', key 
...   print 'new content:', [x for x in new_val if x not in old_val] 
...   print 'removed content:', [x for x in old_val if x not in new_val] 

# now testing on a simple example 
>>> o = {'key1': ['a', 'b', 'c']} 
>>> n = {'key1': ['b', 'c', 'd']} 
>>> comp(o, n) 
evolutions for key1 
new content: ['d'] 
removed content: ['a'] 

警告:此功能仅在new_dict包含old_dict的所有密钥时才有效,否则new_val的创建将失败。您可以轻松地去解决这个担忧,加上按键比较的功能:在old_dict

  • 钥匙不在new_dict被删除的条目;
  • new_dict而不是old_dict是补充。

请将您的结果发布在答案上,以便其他人可以从中受益。

+0

谢谢你Joël。我遵循你的和nmichaels的建议,并试图想用2个字典把改变后的文件也放在这种类型中。找到[diff in dictionaries](http://stackoverflow.com/questions/1165352/fast-comparison-between-two-python-dictionary)与set操作符的好方法。似乎接近我的问题。感谢您的帮助 –

+0

如果您在更新的字典中阅读更新的文件,也许使用此更新的字典的速度更快:)如果您想跟踪差异,我更新了我的答案。 –

+0

谢谢你Joël。最后我用了3张支票。首先是添加的任何键:'code' set_new_dict = set(new_dict.keys()) –