简体   繁体   English

for语句和代码中的替换关键字

[英]for statement and replace keyword in the code

I am very new to Python, actually this is my wk2 trying to follow the book, Learn Python the Hard Way . 我是Python的新手,实际上这是我的wk2试图遵循《艰苦学习Python》一书。

For the code in ex41.py, I have two questions. 对于ex41.py中的代码,我有两个问题。

  1. I don't quite understand why it has the following statement: 我不太明白为什么会有以下陈述:

    for i in range(0, snippet.count("@@@")):

    since snippet.count("@@@") will always be 1, then I would have only 1 value which is 0. Why do we loop through it anyway? 因为snippet.count("@@@")始终为1,所以我只有1个值,即0。为什么我们还是要遍历它呢? Why can't we go straight to set variables param_count and param_names ? 为什么我们不能直接设置变量param_countparam_names

  2. I am also confused by: 我也感到困惑:

     for word in param_names: result = result.replace("@@@", word, 1) 

    I know param_names is a list of words which up to three words, but since @@@ only show up once in both snippet and phrase, how can it get replaced more than 1 times? 我知道param_names是一个最多由三个单词组成的单词列表,但是由于@@@在代码段和短语中仅显示一次,因此如何将其替换超过1次?

Thanks, 谢谢,

import random
from urllib 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 '***'."
}


PHRASE_FIRST = False
if len(sys.argv) == 2 and sys.argv[1] == "english":
    PHRASE_FIRST = True


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[:]



        for word in class_names:
            result = result.replace("%%%", word, 1)

        for word in other_names:
            result = result.replace("***", word, 1)

        for word in param_names:
            result = result.replace("@@@", word, 1)

        results.append(result)

    return results


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, answer = answer, question

            print question

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

Referring to your question 2 ( result = result.replace("@@@", word, 1) ): 参考您的问题2( result = result.replace("@@@", word, 1) ):

Normally, you won't replace it more than one time. 通常,您最多只能更换一次。

With the optional argument "1", only the first "@@@" gets replaced. 使用可选参数“ 1”,仅替换第一个“ @@@”。

For example: 例如:

str = "Hello @@@ hello @@@."

print str.replace("@@@", "world", 1)

print str.replace("@@@", "world", 2) 

Hello world hello @@@.

Hello world hello world.

But in this case it is a loop and it replaces one item at each loop. 但是在这种情况下,这是一个循环,并且在每个循环中替换一项。

str = "Hello @@@ hello @@@."

Loop1

str = "Hello world hello @@@."

Loop2

str = "Hello world hello world."

Finally, in case that you are wondering why the @@@ gets replaced by more then one word. 最后,如果您想知道为什么@@@被一个以上的单词替换。

Take a look to the Join String Method: 看一下Join String方法:

param_names.append(', '.join(random.sample(WORDS, param_count)))

What this method basically does, is transform several strings to one string. 此方法的基本作用是将多个字符串转换为一个字符串。

print ', '.join(["Word1", "Word2"])
Word1, Word2

param_names contains subsequent names of parameters, so if you have ['param1', 'param2'] and a string '(@@@, @@@)' you want the first replace to be result.replace("@@@", 'param1', 1) so it will replace only the first occurrence of @@@ resulting in '(param1, @@@)' . param_names包含参数的后续名称,因此,如果您有['param1', 'param2']和字符串'(@@@, @@@)' ,则希望第一个替换为result.replace("@@@", 'param1', 1)因此它将仅替换第一次出现的@@@导致'(param1, @@@)' Then, you want to replace the second @@@ to have '(param1, param2)' . 然后,您要替换第二个@@@以具有'(param1, param2)' Without the constraint you would end up with '(param1, param1)' , ie all occurrences of @@@ would be replaced with the name of the first parameter. 没有约束,您将最终以'(param1, param1)' ,即所有@@@都将被替换为第一个参数的名称。 The same applies for all other place holders (classes and "others"). 所有其他占位符(类和“其他”)也是如此。

The fact that something seems redundant for some particular input data does not imply that it's redundant in general. 对于某些特定的输入数据来说似乎有些多余的事实并不意味着它通常是多余的。 It is needed for other possible inputs than the example in the script, without this the algorithm would be incorrect. 除脚本中的示例外,还需要其他可能的输入,否则,算法将不正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM