在Python中向后迭代字典

时间:2014-10-05 07:11:16

标签: python python-3.x dictionary

我有一个很长的元素字典,我想删除任何只有一个元素列表的字典条目。 例如

    wordDict={'aardvark':['animal','shell'], 'bat':['animal', 'wings'], 
              'computer':['technology'], 'donut':['food','sweet']}

我想删除计算机'条目,因为它中的列表只有一个元素。我开始迭代wordDict并将字典中的每个条目放在一个单独的列表中,以便它看起来像这样

    wordList=[['animal','shell'],['animal','wings'],['technology'],['food','sweet']]

然后向后遍历该列表,检查列表中每个元素的长度是否大于1.向后,因为向前导致索引在我删除时改变。

所以在wordList中,['技术']被删除了,这就是剩下的

    wordList=[['animal','shell'],['animal','wings'],['food','sweet']]

问题在于,当wordDict变得非常大(100k +单词)时,将wordDict放入列表需要很长时间,然后遍历该列表,我想让它更有效。

我正在考虑向后迭代字典,检查每个条目是否有多个单词,然后删除字典条目(如果它没有)。最后,需要返回的是列表,而不是字典,因此索引最终并不重要,我只是将它们用于排序目的。

有办法做到这一点吗?

5 个答案:

答案 0 :(得分:2)

你可以删除你不想要的元素并创建一个新的字典,使用字典理解,就像这样

>>> {word: items for word, items in wordDict.items() if len(items) > 1}
{'aardvark': ['animal', 'shell'],
 'bat': ['animal', 'wings'],
 'donut': ['food', 'sweet']}

您正在遍历wordDict字典并检查items的长度是否大于1.如果是,则将其包含在正在构建的新字典中,否则不要包括它。

答案 1 :(得分:0)

第一个选项是因为thefourtheye建议相应地尝试rebuild the dictionary并且让只有具有多个元素的列表的元素: -

new_dict = {key:value for key,value in d.iteritems() if len(value) > 1} 

第二个选项是迭代字典并相应地删除项目,但它不会像第一个选项那样有效。

答案 2 :(得分:0)

如果你最后只需要列表,你可以这样做:

wordList = list(filter(lambda x: len(x) > 1, wordDict.values()))

没有必要创建临时字典......

编辑:另一种选择(实际上比上面更清晰,更快)

wordList = list(value for value in wordDict.values() if len(value) > 1)

奖励:如果您不想过滤值,您可以这样做:

wordList = list(filter(bool, wordDict.values()))

编辑:这里的替代方案(这有点奇怪,但是是对的):

wordList = list(value for value in wordDict.values() if value)

空列表(和dicts等)的逻辑值为False

答案 3 :(得分:0)

我认为跟踪长度为1的元素会更快。将元素插入长度为1的字典或对长度为1的元素执行操作时,放置该元素的键在像#34;单身"这样的列表中。然后,如果需要,使用"单打"中的键删除长度= 1的所有元素。它消除了遍历字典的所有元素的需要。

例如,插入字典时:

def insert(wordDict, key, element, singles):
    wordDict[key] = element
    if len(element) == 1:
        singles.append(key)

并且,在对可能改变其长度的元素进行操作时:

def some_operation(key, element, singles):
    # Do something.
    if len(element) == 1:
        singles.append(key)

最后,如果要删除长度为1的所有元素:

def delete_singles(wordDict, singles):
    for k in singles:
        wordDict.pop(k)

现在,只需使用这些函数进行所有插入和修改,并使用delete_single()进行删除。我希望它能够快速运作!

答案 4 :(得分:0)

可以在迭代时修改列表的长度,因为通过向后迭代可以明智地做到这一点。但正如你所注意到的那样,它也很慢(O(nk),其中k为所选择的项目数。

迭代时可能无法更改dict的键,因为这可能会导致重建作为迭代基础的内部哈希数组。一个人必须改为创建一个单独的密钥集合来迭代。

wordDict={'aardvark':['animal','shell'], 'bat':['animal', 'wings'], 
              'computer':['technology'], 'donut':['food','sweet']}

for key in list(wordDict.keys()):
    if len(wordDict[key]) <= 1:
        del wordDict[key]

print(wordDict)

打印

{'aardvark': ['animal', 'shell'], 'bat': ['animal', 'wings'], 'donut': ['food', 'sweet']}