2016-10-02 68 views
-2

我目前正在制作一个使用python的交互式系统,它能够理解和回复。因此,对于机器分析和处理有很多条件。例如。采取下面的代码(仅供参考):有没有办法删除太多的其他条件?

if ('goodbye') in message:       
     rand = ['Goodbye Sir', 'Jarvis powering off in 3, 2, 1, 0'] 
     speekmodule.speek(rand,n,mixer) 
     break 

    if ('hello') in message or ('hi') in message: 
     rand = ['Wellcome to Jarvis virtual intelligence project. At your service sir.'] 
     speekmodule.speek(rand,n,mixer) 

    if ('thanks') in message or ('tanks') in message or ('thank you') in message: 
     rand = ['You are wellcome', 'no problem'] 
     speekmodule.speek(rand,n,mixer) 

    if message == ('jarvis'): 
     rand = ['Yes Sir?', 'What can I doo for you sir?'] 
     speekmodule.speek(rand,n,mixer) 

    if ('how are you') in message or ('and you') in message or ('are you okay') in message: 
     rand = ['Fine thank you'] 
     speekmodule.speek(rand,n,mixer) 

    if ('*') in message: 
     rand = ['Be polite please'] 
     speekmodule.speek(rand,n,mixer) 

    if ('your name') in message: 
     rand = ['My name is Jarvis, at your service sir'] 
     speekmodule.speek(rand,n,mixer) 

那么,有没有一种方式,我可以取代所有这些,如果其他条件?因为条件会更多,并且会使执行速度变慢。

+1

第一步是删除不必要的parens,即只写'if'hello''。 – skovorodkin

+0

这是一个使用字典的解决方案:http://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python – imant

+0

是的,你可以使用建议的字典来实现一种“切换...案例...” ”。但用RegEx为了实现“消息中的单词”。但是,它不会降低算法的复杂性:您必须检查所有情况。 –

回答

1

做一个独特的 “如果”:

if 'goodbye' in message:       
    rand = ['Goodbye Sir', 'Jarvis powering off in 3, 2, 1, 0'] 

elif 'hello' in message or 'hi' in message: 
    rand = ['Wellcome to Jarvis virtual intelligence project. At your service sir.'] 

elif 'thanks' in message or 'tanks' in message or ('thank you') in message: 
    rand = ['You are wellcome', 'no problem'] 

elif message == 'jarvis': 
    rand = ['Yes Sir?', 'What can I doo for you sir?'] 

elif 'how are you' in message or 'and you' in message or ('are you okay') in message: 
    rand = ['Fine thank you'] 

elif '*' in message: 
    rand = ['Be polite please'] 

elif 'your name' in message: 
    rand = ['My name is Jarvis, at your service sir'] 

else: 
    raise NotImplementedError("What to do?") 

speekmodule.speek(rand, n, mixer) 

用正则表达式的映射:

mapping = { 
    r"\bgoodbye\b": ['Goodbye Sir', 'Jarvis powering off in 3, 2, 1, 0'], 
    r"\bhello\b": ['Wellcome to Jarvis virtual intelligence project. At your service sir.'], 
    ...} 

for regex, rand in mapping.items(): 
    if re.search(message, flags=re.I): 
     break 
else: 
    raise NotImplementedError("What to do?") 
speekmodule.speek(rand, n, mixer) 

它是由你来决定。

0

if/elif/else是一种在Python中构造这种代码的自然方式。正如@imant指出的那样,在简单分支的情况下,您可以使用基于字典的方法,但我在您的谓词中看到一些复杂的逻辑,因此您必须在任何情况下检查所有谓词,并且不会有任何性能获得另一个代码结构。

虽然它可能是一个有点更具可读性和更容易,如果你分解出你的谓词和操作这样的维护:

from collections import OrderedDict 

def goodbye_p(message): 
    return 'goodbye' in message 

def goodbye_a(): 
    rand = ['Goodbye Sir', 'Jarvis powering off in 3, 2, 1, 0'] 
    # As @Moinuddin Quadri I also assume that your `speek` method 
    # says random message from a list. 
    # Otherwise you can use `random.choice` method 
    # to get a random message out of a list: `random.choice(messages)`. 
    speekmodule.speek(rand, n, mixer) 


def hello_p(message): 
    return 'hello' in message or 'hi' in message 

def hello_a(): 
    rand = ['Wellcome to Jarvis virtual intelligence project. At your service sir.'] 
    speekmodule.speek(rand, n, mixer) 

# Use `OrderedDict` instead of `dict` to control order 
# of checks and actions. 
branches = OrderedDict([ 
    # (predicate as key, action as value) 
    (goodbye_p, goodbye_a), 
    (hello_p, hello_a), 
]) 

for predicate, action in branches.items(): 
    if predicate(message): 
     action_result = action() 
     # You can add some logic here based on action results. 
     # E.g. you can return some special object from `goodbye_a` 
     # and then shut down Jarvis here. 
     # Or if your actions are exclusive, you can add `break` here. 

如果所有的谓词是相同的,并且只包含子串检查,然后将其可能会更高效地将元组(例如('hello', 'hi'))作为字典键。然后你就可以在这些键这样的迭代:

for words, action in branches.items(): 
    if any(word in message for word in words): 
     action() 
0

首先创建一个键一个dict对象作为字符串的tuple要匹配你的message,它与你的贾维斯是假设响应值string关联。例如:

jarvis_dict = { 
    ('goodbye',) : ['Goodbye Sir', 'Jarvis powering off in 3, 2, 1, 0'], 
    ('hello', 
    'hi')  : ['Wellcome to Jarvis virtual intelligence project. At your service sir.'], 
    ('thanks', 
    'tanks', 
    'thank you') : ['You are wellcome', 'no problem'], 
    ('jarvis',) : ['Yes Sir?', 'What can I doo for you sir?'], 
    ('how are you', 
    'and you', 
    'are you okay'): ['Fine thank you'], 
    ('*',)  : ['Be polite please'], 
    ('your name',): ['My name is Jarvis, at your service sir'] 
} 

现在迭代的你dict每个键来检查任何子串是否是消息的一部分,如果有任何匹配,调用speekmodule.speek(rand,n,mixer)功能:

for key, value in jarvis_dict.items(): 
    if any(item in message for item in key): 
     speekmodule.speek(value, n, mixer) 

注意:这里我假设您的代码中的speekmodule.speek(value, n, mixer)正在工作,因为您的代码中没有关于该声明的信息。我刚刚将rand替换为value,因为它与您的代码中使用的dict返回的str列表相同。

+0

您可能希望使用'random.choice(value)'从一组预定义的变体中获得随机答案。 – skovorodkin

+2

正如我在答案中已经提到的那样,我不确定'speekmodule.speek()'函数的行为如何,并且我假定OP中的这个函数工作正常(并且调用了'random.choice(value)'内部由'.speek()'函数)。我的代码旨在提供与OP相同的功能。 –

0

使用字典:

someCollections = { 
    'goodbye': "Something1", 
    'hello': "Somthing2", 
    ... 
} 

speekmodule(someCollections [SomeKey],...) 
+3

对变量使用内置名称(例如'dict')是不好的做法。 – Dartmouth

+0

答复已更新。 – David

相关问题