2017-04-24 129 views
1

我使用的是學習Python的學習Python中硬件的方式,我跑入'dict_keys' object does not support indexing error當我運行是作爲示例提供下面的代碼:「dict_keys」對象不支持索引

import random 
from urllib.request import urlopen 
import sys 

WORD_URL = "http://learncodethehardway.org/words.txt" 
WORDS = [] 

PHRASES = { 
    "class %%%(%%%):": 
     "Make a class named %%% that is-a %%%.", 
    "class %%%(object):\n\tdef __init__(self, ***)" : 
     "class %%% has-a __init__ that takes self and *** parameters.", 
    "class %%%(object):\n\tdef ***(self, @@@)": 
     "class %%% has-a function named *** that takes self and @@@ parameters.", 
    "*** = %%%()": 
     "Set *** to an instance of class %%%.", 
    "***.***(@@@)": 
     "From *** get the *** function, and call it with parameters self, @@@.", 
    "***.*** = '***'": 
     "From *** get the *** attribute and set it to '***'." 
} 

# do they want to drill phrases first 
if len(sys.argv) == 2 and sys.argv[1] == "english": 
    PHRASE_FIRST = True 
else: 
    PHRASE_FIRST = False 

# load up the words from the website 
for word in urlopen(WORD_URL).readlines(): 
    WORDS.append(word.strip()) 


def convert(snippet, phrase): 
    class_names = [w.capitalize() for w in 
        random.sample(WORDS, snippet.count("%%%"))] 
    other_names = random.sample(WORDS, snippet.count("***")) 
    results = [] 
    param_names = [] 

    for i in range(0, snippet.count("@@@")): 
     param_count = random.randint(1,3) 
     param_names.append(', '.join(random.sample(WORDS, param_count))) 

    for sentence in snippet, phrase: 
     result = sentence[:] 

     # fake class names 
     for word in class_names: 
      result = result.replace("%%%", word, 1) 

     # fake other names 
     for word in other_names: 
      result = result.replace("***", word, 1) 

     # fake parameter lists 
     for word in param_names: 
      result = result.replace("@@@", word, 1) 

     results.append(result) 

    return results 


# keep going until they hit CTRL-D 
try: 
    while True: 
     snippets = PHRASES.keys() 
     random.shuffle(snippets) 

     for snippet in snippets: 
      phrase = PHRASES[snippet] 
      question, answer = convert(snippet, phrase) 
      if PHRASE_FIRST: 
       question = list(answer) 
       answer = list(question) 

      print(question) 

      input("> ") 
      print("ANSWER: %s\n\n" % answer) 
except EOFError: 
    print("\nBye") 

此代碼適用於Python 2.x,我使用的是Python 3.5。我看到以下帖子,但無法將解決方案翻譯爲上面的文章:TypeError: 'dict_keys' object does not support indexing。任何幫助表示讚賞。

+0

你會這麼好心接受答案了給出的答案,讓任何人訪問您的問題(甚至訪問過它之前)可以看,問題解決了嗎? – Claudio

回答

0

由於在Python 2和3中對字符串/字節類型(影響3行代碼)的不同處理和對象的索引(1行受影響)存在兩個問題(在其他答案中提及)。運行正常調整(4行代碼)的完成之後:

import random 
from urllib.request import urlopen 
import sys 

WORD_URL = "http://learncodethehardway.org/words.txt" 
WORDS = [] 

PHRASES = { 
    "class %%%(%%%):": 
     "Make a class named %%% that is-a %%%.", 
    "class %%%(object):\n\tdef __init__(self, ***)" : 
     "class %%% has-a __init__ that takes self and *** parameters.", 
    "class %%%(object):\n\tdef ***(self, @@@)": 
     "class %%% has-a function named *** that takes self and @@@ parameters.", 
    "*** = %%%()": 
     "Set *** to an instance of class %%%.", 
    "***.***(@@@)": 
     "From *** get the *** function, and call it with parameters self, @@@.", 
    "***.*** = '***'": 
     "From *** get the *** attribute and set it to '***'." 
} 

# do they want to drill phrases first 
if len(sys.argv) == 2 and sys.argv[1] == "english": 
    PHRASE_FIRST = True 
else: 
    PHRASE_FIRST = False 

# load up the words from the website 
for word in urlopen(WORD_URL).readlines(): 
    WORDS.append(word.strip()) 


def convert(snippet, phrase): 
    class_names = [w.capitalize() for w in 
        random.sample(WORDS, snippet.count("%%%"))] 
    other_names = random.sample(WORDS, snippet.count("***")) 
    results = [] 
    param_names = [] 

    for i in range(0, snippet.count("@@@")): 
     param_count = random.randint(1,3) 
     param_names.append(', '.join(random.sample(str(WORDS), param_count))) 

    for sentence in snippet, phrase: 
     result = sentence[:] 
     # print(type(result)) 

     # fake class names 
     for word in class_names: 
      # print(type(word)) 
      result = result.replace("%%%", word.decode("utf-8"), 1) 

     # fake other names 
     for word in other_names: 
      result = result.replace("***", word.decode("utf-8"), 1) 

     # fake parameter lists 
     for word in param_names: 
      result = result.replace("@@@", word.decode("utf-8"), 1) 

     results.append(result) 

    return results 


# keep going until they hit CTRL-D 
try: 
    while True: 
     for i, item in enumerate(PHRASES.keys()): 
      print(i, "###", item) 

     snippets = list(PHRASES.keys()) 
     random.shuffle(snippets) 

     for snippet in snippets: 
      phrase = PHRASES[snippet] 
      question, answer = convert(snippet, phrase) 
      if PHRASE_FIRST: 
       question = list(answer) 
       answer = list(question) 

      print(question) 

      input("> ") 
      print("ANSWER: %s\n\n" % answer) 
except EOFError: 
    print("\nBye") 
0

嘗試用這種

snippets = list(PHRASES.keys())

更換此

snippets = PHRASES.keys()

因爲是說,在你提供的鏈接,dict.keys()不蟒蛇返回一個列表3.

0

所以你需要知道Python 2.X之間有一些區別和Python 3.5.x.

從@jprokbelly答案將讓你的存在方式的一部分,但你也需要修改在convert函數的代碼,因爲urlopenurllib.request將返回字節流,而不是字符串,這將導致錯誤信息:

TypeError: Can't convert 'bytes' object to str implicitly 

所以如果你想在Python 3.5.x中使用這段代碼,那麼你至少需要做兩件事。

  1. 更改convert方法向snippets = PHRASES.keys()snippets = list(PHRASES.keys()]
  2. 更改開頭:

    def convert(snippet, phrase): 
        class_names = [w.capitalize() for w in random.sample(WORDS, snippet.count("%%%"))] 
        other_names = random.sample(WORDS, snippet.count("***")) 
        class_names = [name.decode('UTF-8') for name in class_names] 
        other_names = [name.decode('UTF-8') for name in other_names] 
    

你另一種選擇是設置你的開發環境中使用的virtualenv和運行Python 2.7.x中的代碼。