2017-04-24 128 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中的代码。