2015-10-01 26 views
2

我被分配到列表列表lexcicographicaly中。使用OrderedDictionary對分組Anagrams進行分組:類型錯誤問題

下面是測試情況之一:

輸入: eat tea tan ate nat bat

輸出:

ate eat tea bat nat tan

不過,我不斷收到這樣的類型錯誤:TypeError: 'type' object is not iterable

我設法通過將anagramDict = OrderedDict(list)更改爲anagramDict = defaultdict(list)來修復此錯誤,但這導致代碼在每次運行程序時都以隨機順序打印所有三行。

有沒有辦法解決這個問題,以便程序像上面顯示的那樣輸出

這是我迄今所做的:

import sys 
from collections import * 
def findAnagrams(string): 
    anagramDict = OrderedDict(list) 
    for word in string: 
     key = ''.join(sorted(word)) 
     anagramDict[key].append(word) 
    return anagramDict 

def main(): 
    for string in sys.stdin: 
     stringList = string.split() 
     if len(stringList) == 0: 
      break 
     anagramDict = findAnagrams(stringList) 
     for key,anagrams in anagramDict.items(): 
      if len(anagrams) >=1: 
       print(' '.join(sorted(anagrams))) 
     print() 
main() 

注:運行此程序的機器從標準輸入/鍵盤讀取輸入並打印輸出到控制檯(標準輸出)。

回答

4

你不能通過OrderedDictlist這樣的論點。因爲當使用OrderedDict時,它的參數應該是可迭代的(如元組列表等),從中將創建有序字典。

使用OrderedDict時,您可以使用dict.setdefault()來獲得相似的效果。示例 -

def findAnagrams(string): 
    anagramDict = OrderedDict() 
    for word in string: 
     key = ''.join(sorted(word)) 
     anagramDict.setdefault(key, []).append(word) 
    return anagramDict 

此外,還有一點需要注意的是OrderedDict保持在其中的密鑰發送給它的命令,它不字典順序排序。

爲此,一個簡單的方法是在嘗試對main()函數進行迭代時對其進行排序。示例 -

def main(): 
    s = [input()] 
    for string in s: 
     stringList = string.split() 
     if len(stringList) == 0: 
      break 
     anagramDict = findAnagrams(stringList) 
     for key, anagrams in sorted(anagramDict.items() ,key=lambda x: sorted(x[1])): 
      if len(anagrams) >=1: 
       print(' '.join(sorted(anagrams))) 
     print() 

對於這種方法,你甚至不需要使用OrderedDict,你可以簡單地用一個defaultdict爲你使用,或與dict.setdefault正常的字典。

演示 -

輸入 -

eat tea tan ate nat bat 

輸出 -

ate eat tea 
bat 
nat tan 
+0

謝謝你幫我出一次。這避免了代碼得到TypeError。但是,我仍然很難獲得正確的輸出順序。有什麼建議麼? – Eninfo

+0

@AnandSKumar他希望每個問題的字典順序。 – zstewart

+0

@Eninfo'OrderedDict'的意思是「保留您添加項目的順序」而不是「對添加的項目進行排序」 – zstewart