Python输出不情愿地陷入for循环

时间:2015-12-26 17:31:45

标签: python python-2.7 for-loop

我正在努力制作一个像人类一样“谈话”的节目(是的,我知道,大梦)。

代码:

#!/usr/bin/python

import re
from speech import say as talk
from random import randint

yesnoquestion = ["do", "is", "can", "are", "would", "am"]
greetings = ["hi", "hello", "greetings"]

def say(phrase):
    print phrase
    talk(phrase)

def question():
    randominteger = randint(1,2)
    if words[0] in yesnoquestion and randominteger == 1:
        say("Yes.")
    elif words[0] in yesnoquestion and randominteger == 2:
        say("No.")
    elif "name" and "your" in words:
        say("I think I have already told you. My name is Eliza.")
    else:
        say("Just because. ")

def other():
    for listelement in words:
        if listelement in greetings:
            say("Nice to meet you. ")
        elif listelement == "name":
            indices = [i+2 for i, word in enumerate(words) if word == 'name']
            names = [words[i] for i in indices if i < len(words)]
            for usname in names:
                say("Hi, " + usname.title() + ".")
        else:
            say("I see. ")
say("Hi, my name is Eliza.")
words = []

while 1:
    text = raw_input("> ")
    words = map(lambda x:x.lower(), re.sub("[^\w]", " ",  text).split())
    #print words
    if text[-1] == "?":
        question()
    else:
        other()

问题在于,当我输入一个句子而不是一个问题时,输出会重复,因为该句子中有单词。

C:\Users\chef> python C:\Users\chef\Desktop\eliza.py
Hi, my name is Eliza.
> I love pizza.
I see.
I see.
I see.
> You seem to have encountered a bug.
I see.
I see.
I see.
I see.
I see.
I see.
I see.
>

我该如何解决这个问题?我很确定这是由for循环引起的,但我不知道如何。

4 个答案:

答案 0 :(得分:3)

您正在回复中的每个字词。在说()或以另一种方式处理单词后添加中断。

for listelement in words:
    if listelement in greetings:
        say("Nice to meet you. ")
        break
    elif listelement == "name":
        indices = [i + 2 for i, word in enumerate(words) if word == 'name']
        names = [words[i] for i in indices if i < len(words)]
        for usname in names:
            say("Hi, " + usname.title() + ".")
            break    
    else:
        say("I see. ")
        break

答案 1 :(得分:0)

def other():
    for listelement in words:
        if listelement in greetings:
            say("Nice to meet you. ")
            return  # no need to continue with the loop
        elif listelement == "name":
            indices = [i+2 for i, word in enumerate(words) if word == 'name']
            names = [words[i] for i in indices if i < len(words)]
            for usname in names:
                say("Hi, " + usname.title() + ".")
            return  # no need to continue with the loop
    say("I see. ")  # there are no greetings and "name" is not among words

您的代码的问题在于您可能不应该从函数返回。你也为每个不是“名字”或不在问候中的单词称为“说”功能。所以移动

是有道理的
say("I see. ")

在循环之外。

更新:master_Alish答案的一个简单反例:如果你有

words = ["My", "name", "is", "Bob"]

然后你不会用

打招呼
say("Hi, " + usname.title() + ".")

因为你将在第一次迭代中掉到'else'部分并从函数返回,所以永远不要在变量“words”中找到“name”元素。

答案 2 :(得分:0)

“我喜欢披萨”是有意义的,我会看到3次打印,因为你在句子的每个单词上迭代3次,而对于每个单词,如果它不是问候语或名字,你打印“我看到”

您可以尝试累积输出句子,并在最后打印出来:

type = None
all_names = []
for listelement in words:
    if listelement in greetings:
        type = 'greeting'
    elif listelement == "name":
        indices = [i+2 for i, word in enumerate(words) if word == 'name']
        names = [words[i] for i in indices if i < len(words)]
        all_names += names



if type == 'greeting':
    say("Nice to meet you. ")
elif type == 'names':
    for usname in names:
        say("Hi, " + usname.title() + ".")
else:
    say("I see. ")

答案 3 :(得分:0)

我猜你的意图是这个。

尝试并回答我有任何问题。

问题是你的for循环遍历你所分割的所有单词并根据你输入的单词数激活say()。

def other():
    if any(word in greetings for word in words):
        say("Nice to meet you. ")
    elif "name" in words:
        indices = [i+2 for i, word in enumerate(words) if word == 'name']
        names = [words[i] for i in indices if i < len(words)]
        for usname in names:
            say("Hi, " + usname.title() + ".")
    else:
        say("I see. ")