Python ';dict#u键';对象不支持索引

Python ';dict#u键';对象不支持索引,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,我正在用学习Python的艰苦方法学习Python,当我运行以下作为示例提供的代码时,我遇到了“dict_keys”对象不支持索引错误: import random from urllib.request import urlopen import sys WORD_URL = "http://learncodethehardway.org/words.txt" WORDS = [] PHRASES = { "class %%%(%%%):": "Make a class

我正在用学习Python的艰苦方法学习Python,当我运行以下作为示例提供的代码时,我遇到了
“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")
这段代码是为Python2.x编写的,我使用的是Python3.5。我看到了以下帖子,但无法将解决方案转换为上述内容:。非常感谢您的帮助。

请尝试更换此设备

snippets=PHRASES.keys()

用这个

snippets=list(PHRASES.keys())


正如在您提供的链接中所说,
dict.keys()
在Python3中不返回列表。

因此您需要注意Python2.X和Python3.5.X之间有一些区别

来自@jprokbelly的答案将为您提供部分帮助,但您还需要修改
convert
函数中的代码,因为
urlopen
来自
urllib.request
urlopen
将返回字节流而不是字符串,这将导致错误消息:

TypeError: Can't convert 'bytes' object to str implicitly
因此,如果您想在Python3.5.x中使用这段代码,那么您至少需要做两件事

  • snippets=PHRASES.keys()
    更改为
    snippets=list(PHRASES.keys()]
  • convert
    方法的开头更改为:

    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中运行代码。

    这里有两个问题(在其他答案中提到),因为字符串/字节类型的处理不同(影响3行代码)和对象的索引不同(影响1行)在Python 2和3中。在完成调整(在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")
    

    您是否愿意从给出的答案中接受答案,以便任何访问您的问题(甚至在访问之前)的人都能看到问题已经解决?