【问题标题】:How do I deal with a logical expression in Python?如何处理 Python 中的逻辑表达式?
【发布时间】:2013-11-27 13:42:51
【问题描述】:
假设我得到了 ie 格式的逻辑表达式。 AvBv~C->D 。它由布尔元素和运算符组成,如(v,~,->)(析取、否定、暗示)。
我需要存储这些表达式以及它们所包含的每个元素。每个元素也应该有一个描述,所以我想我必须创建一个代表它们的类(带有字段representation和description,即element1.representation="A"和element1.description="This is element A",但我不确定这是否是pythonic方式,也许将名称和描述作为列的二维数组会是一个更好的主意,因为名称都是唯一的。
- 我应该使用哪种数据结构来存储这样的表达式?请注意,我需要存储不同类型的元素和运算符,然后能够将它们恢复为逻辑表达式并对它们进行操作。
- 我应该创建方法来识别每个元素和运算符来处理逻辑运算还是有更好的方法?也许使用 Lex-Yacc 之类的解析器或其他处理这些的库?
如果我不太清楚,请原谅我,但我来自 Java,我无法在同一数据结构中存储不同类型的元素。
【问题讨论】:
标签:
python
regex
logic
logical-operators
ply
【解决方案1】:
通过声明__and__、__or__ 和__invert__ 方法,您可以使用&、| 和~ 运算符来定义您的表达式。
class Element(object):
def __init__(self, elt_id, elt_description=None):
self.id = elt_id
self.description = elt_description
if self.description is None:
self.description = self.id
def __or__(self, elt):
return CombinedElement(self, elt, op="OR")
def __and__(self, elt):
return CombinedElement(self, elt, op="AND")
def __invert__(self):
return CombinedElement(self, op="NOT")
def __str__(self):
return self.id
class CombinedElement(Element):
def __init__(self, elt1, elt2=None, op="NOT"):
# ID1
id1 = elt1.id
if isinstance(elt1, CombinedElement):
id1 = '('+id1+')'
# ID2
if elt2 is not None:
id2 = elt2.id
if isinstance(elt2, CombinedElement):
id2 = '('+id2+')'
# ELT_ID
if op == "NOT" and elt2 is None:
elt_id = "~"+id1
elif op == "OR":
elt_id = id1+" v "+id2
elif op == "AND":
elt_id = id1+" ^ "+id2
# SUPER
super(CombinedElement, self).__init__(elt_id)
a = Element("A")
b = Element("B")
c = Element("C")
d = Element("D")
e = Element("E")
print(a&b|~(c&d)|~e)
输出:
((A ^ B) v (~(C ^ D))) v (~E)
【解决方案2】:
- 创建表示表达式中每个元素的树形数据结构。
- 您确实可以使用解析器生成器从给定的字符串生成上述数据结构。
例如,一个连词可以表示如下,类似的方法可以用于变量:
class Node:
operator = "AND"
left_node = None
right_node = None
description = "text"
value = None
class Node:
operator = "VAR"
left_node = None
right_node = None
description = "text"
value = "B"
然后你可以用这些节点组成一棵树。
例如:A^B 可以表示为 Node 和 AND,其中 left_node 是 VAR 节点 (value=A),right_node 也是 VAR 节点(value=B)。