好的,这就是我的困境:
我正在为一个subreddit开发FAQ bot。我遇到布尔逻辑问题,可以使用一对更有经验的眼睛(这是我在Python中的第一次冒险)。现在机器人基本上是垃圾邮件我创建的测试subreddit。而不是分享这些特定信息,这是一个显示我遇到的确切问题的例子:
#Define Key Words
##################################
#System Requirements Definitions
sysReq1 = ('system requirements' and '?')
sysReq2 = ('can' and ('handle' or 'play' or 'run') and ('netbook' or 'notebook' or 'pc' or 'mac' or 'macbook' or 'laptop' or 'comp' or 'computer') and '?')
#System Requirements Response
sysReqResponse = 'PROGRESS'
##################################
testString1 = "i hate this"
#intended result for 1: nothing
testString2 = "is that real?"
#intended result for 2: nothing
testString3 = "What are the system requirements?"
#intended result for 3: 'PROGRESS'
print testString1
if (sysReq1 or sysReq2) in testString1.lower():
print sysReqResponse
print testString2
if (sysReq1 or sysReq2) in testString2.lower():
print sysReqResponse
print testString3
if (sysReq1 or sysReq2) in testString2.lower():
print sysReqResponse
运行时,会显示:
i hate this
is that real?
PROGRESS
What are the system requirements?
PROGRESS
它不断返回testString2的值。我认为它与'?'有关但真的不知道如何或为什么或如何处理它。救命啊!
编辑:这是我想要显示的内容:
运行时,会显示:
i hate this
is that real?
What are the system requirements?
PROGRESS
到目前为止,我发现如果我将sysReq1 = ('system requirements' and '?')
更改为sysReq1 = 'system requirements' '?'
并仅检查if
sysReq1
,则会返回战斗值。问题是我真的需要那些or
语句来减少混乱/冗余。
sysReq2存在的原因是因为有些人对同一个答案提出了不同的问题:
可以在我的上网本上运行吗?
我的电脑可以处理吗?
我可以在我的Mac上播放吗?
这是排除'我能够'的变化,但你明白了。所有这些都应返回相同的值(在本例中为“PROGRESS”)
答案 0 :(得分:1)
两个问题。首先,您不能使用and
和or
“存储”某种比较运算符以供日后使用。当您编写and
和or
时,会立即评估结果。 the documentation。
其次,您不能以and
方式使用or
和in
。 in
不会“分发”and
和or
。写('A' and 'B') in x
并不意味着“x中的A和x中的B”。它首先评估('A' and 'B')
(在这种情况下会给你'B'
),然后检查单个结果是否在x
。
使用简单的运算符无法实现您的目标。没有办法只使用and
和or
运算符来存储您可以稍后应用的复杂查询。您将不得不将标准转换为函数,并使用“测试字符串”作为参数调用它们:
def sysReq1(x):
return 'system requirements' in x and '?' in x
>>> testString2 = "is that real?"
... testString3 = "What are the system requirements?"
... print testString2
... if sysReq1(testString2.lower()):
... print "2 passed the test"
... print testString3
... if sysReq1(testString3.lower()):
... print "3 passed the test"
is that real?
What are the system requirements?
3 passed the test
我建议你通过the Python tutorial来处理Python的基础知识。
答案 1 :(得分:1)
我认为any
,all
和generators可以帮到你。
#Define Key Words
##################################
#System Requirements Definitions
sysReq1 = ['system requirements', '?']
sysReq2 = [['can']
,['handle', 'play', 'run']
,['netbook', 'notebook', 'pc', 'mac', 'macbook', 'laptop', 'comp', 'computer']
,['?']
]
def test(testString):
lowerTestString = testString.lower()
return all(i in lowerTestString for i in sysReq1) or all(any(j in lowerTestString for j in i) for i in sysReq2)
#System Requirements Response
sysReqResponse = 'PROGRESS'
##################################
testString1 = "i hate this"
#intended result for 1: nothing
testString2 = "is that real?"
#intended result for 2: nothing
testString3 = "What are the system requirements?"
#intended result for 3: 'PROGRESS'
print testString1
if test(testString1):
print sysReqResponse
print testString2
if test(testString2):
print sysReqResponse
print testString3
if test(testString3):
print sysReqResponse
该功能并非绝对必要,但它确实使代码更易于维护。如果您需要更改支票,它只会在一个地方更改。
首先,我们将两组字符串转换为列表和列表列表。然后,要求变为“字符串必须包含sysReq1
的所有元素或sysReq2
的每个子列表中的至少一个元素。”
我们通过将生成器与any
和all
函数组合来完成检查此条件。在存储lower
以避免重复调用它之后,我们创建了一个布尔值的生成器(相当于迭代器)。每个布尔告诉我们降低后是否包含sysReq1
的单个元素。然后我们将这个迭代器传递给第一个all
,它检查列表是否包含所有True
个。如果是,则all
函数返回True
,第二次检查被短路。否则,它返回False
并且Python移过or.
对sysReq2
的检查更复杂。首先,我们为每个子列表创建一个布尔生成器;这是在any
电话中。此列表包含一组布尔值,表示子列表中的每个元素是否都在降低的字符串中。如果此布尔值列表中的任何元素(基于子列表)为any
,则True
调用将返回True
。 (顺便说一下,它是短路的,因为我们使用的是生成器,所以True
之后的检查甚至都没有运行,就像我们使用了一个列表一样。)然后我们创建另一个生成器;这个包含每个子列表测试的结果(所有any
调用)。然后在此生成器上调用all
,该生成器检查问题是否包含所有子列表中的元素。
我会注意到,如果用户直接输入,他们可以输入无意义的问题。例如,'Play can netbook kuguekf ugifugfj ugufsgjf nugjfgjfgj?'
会通过此检查。
使用generator来运行返回布尔值的测试。使用any
和all
组合布尔值的可迭代。
根据评论,这是一个替代解决方案split
按空格输入字符串并使用set
而不是list
s。我还从您列出的示例问题中添加了一个测试用例,以确保or
的第二部分被命中。
#Define Key Words
##################################
#System Requirements Definitions
sysReq1 = set(['system', 'requirements'])
sysReq2 = [set(['can'])
,set(['handle', 'play', 'run'])
,set(['netbook', 'notebook', 'pc', 'mac', 'macbook', 'laptop', 'comp', 'computer'])
]
def test(testString):
if not testString.endswith('?'):
return False
lowerTestString = set(testString.rstrip('?').lower().split())
return lowerTestString.issuperset(sysReq1) or all(not lowerTestString.isdisjoint(i) for i in sysReq2)
#System Requirements Response
sysReqResponse = 'PROGRESS'
##################################
testString1 = "i hate this"
#intended result for 1: nothing
testString2 = "is that real?"
#intended result for 2: nothing
testString3 = "What are the system requirements?"
#intended result for 3: 'PROGRESS'
testString4 = "Can my PC handle it?"
#intended result for 4: 'PROGRESS'
print testString1
if test(testString1):
print sysReqResponse
print testString2
if test(testString2):
print sysReqResponse
print testString3
if test(testString3):
print sysReqResponse
print testString4
if test(testString4):
print sysReqResponse
我认为这是相当简单的。请注意,set
构造函数采用可迭代的方式,因此我只是为此传递列表。 “不相交”部分可能有点令人困惑;它只是确保交叉点不是空的。我使用它希望函数被实现,以便它不计算整个交集。问号是有问题的,因为它没有被空格分隔,所以我只是确保字符串以问号结束并且rstrip
将其关闭。
实际上,这个实现可能比具有大量生成器的实现更清晰,更易于维护。
答案 2 :(得分:0)
在python中,包含BOOLEAN OPERATORS的表达式的输出不必是BOOLEAN(http://docs.python.org/2/library/stdtypes.html)
例如,sysReq1 = ('system requirements' and '?')
将生成sysReq1='?'
并在此注意sysReq1
不是布尔值,而是等于QUESTION MARK的字符串。同样,sysReq2
也将等于?
。此外,在上面的链接中查找TRUTH VALUE TESTING,因为这将解释哪些值将被视为FALSE表达式。