简体   繁体   English

在python中检查(“ and”,“ or”)优先级的简单方法

[英]Easy way to check precedence of ( “and”, “or”) in python

I have a python list like this 我有一个像这样的python列表

[True, "and", False, "or", False, "or", True ....]

How to operate them and find the boolean value (True and False or False or True ...) efficiently ? 如何操作它们并有效地找到布尔值(True和False或False或True ...)?

I know and has more precedence than or. 我知道并且比或具有更高的优先级。 So I know about the way where we break the list about every or and take or of booleans computed from each list. 因此,我知道了我们如何打破每个列表的和从每个列表计算出的布尔值的布尔值的方式。

I want to know is there a more easy way to do so ? 我想知道还有更简单的方法吗?

if my_list = [True, "and", False, "or", False, "or", True ] this will output
True as (True and False) or False or True = False or False or True which is True. 

if my_list = [True, "and", True, "or", False, "or", False ] this will output 
True as (True and True) or False or False = True or False or False which is True

if my_list = [False, "or", False, "and", False, "and", True ] = False or False which is False

One way to do operator precedence is through the shunting-yard algorithm , which requires a stack: 运算符优先级的一种方法是通过调车场算法 ,该算法需要堆栈:

def evaluate(e):
    ops = {'and': 1, 'or': 0} 
    op_stack = []
    output = []
    for i in e:
        if i in ops:
            while op_stack and ops[op_stack[-1]] > ops[i]:
                output.append(op_stack.pop())
            op_stack.append(i)
        else:
            output.append(i)
    op_stack.reverse()
    output.extend(op_stack)

    stack = []
    for i in output:
        #print(stack, i)
        if i in ops:
            a, b = stack.pop(), stack.pop()
            if i == 'and':
                i = a and b
            else:
                i = a or b
        stack.append(i)
    return stack[0]

>>> evaluate([True, "and", False, "or", False, "or", True])
True
>>> evaluate([True, 'or', True, 'and', False])
True

The other way to do operator precedence is a recursive precedence climbing algorithm: 进行运算符优先级的另一种方法是递归优先级爬升算法:

ops = {'and': 1, 'or': 0}

def tokenizer(l):
    for i in l:
        o = yield i
        while o:
            yield None
            o = yield o

def evaluate(token, prec=0):
    lhs = next(token)

    while True:
        op = next(token, None)
        if op is None or ops[op] < prec:
            if op: token.send(op)
            break

        rhs = evaluate(token, ops[op]+1)
        #print(lhs, op, rhs)
        lhs = lhs and rhs if op == 'and' else lhs or rhs
    return lhs

>>> evaluate(tokenizer([True, 'or', True, 'and', False]))
True
>>> evaluate(tokenizer([True, "and", False, "or", False, "or", False, "or",
...                     True, "and", False, "or", False, "or", False]))
False

With the prints: 与印刷品:

>>> evaluate(tokenizer([True, "and", False, "or", False, "or", False, "or",
...                     True, "and", False, "or", False, "or", False]))
True and False
False or False
False or False
True and False
False or False
False or False
False or False
False

IIUC you could use map , isinstance : IIUC您可以使用mapisinstance

l = [True, "and", False, "or", False, "or", True]
res = list(map(lambda x: isinstance(x, bool), l))

print(res)
[True, False, True, False, True, False, True]

Not sure if this will be faster, but: 不知道这是否会更快,但是:

l = [True, "and", False, "or", False, "or", False, "or", True, "and", False, "or", False, "or", False]
eval(' '.join([ str(z) for z in l]))

result: 结果:

False

If I understand correctly this should be the simplest (less elegant) solution 如果我正确理解,这应该是最简单(不太优雅)的解决方案

expression = [True, "and", False, "or", False, "or", True]


def eval_expr( value1, operator, value2):
    if operator == 'and':
        return value1 and value2

    else:
        return value1 or value2


result = None

while len(expression) != 1:
    v1 = expression.pop()
    op =  expression.pop()
    v2 = expression.pop()
    partial_result = eval_expr(v1, op, v2)
    expression.insert(0, partial_result)
    result = partial_result

print result

@Iliyan 's answer is correct. @Iliyan的答案是正确的。 Less hacky than me. 没有我那么客气。

I came up with a trick to do so. 我想出了一个办法。

my_list = [True, "and", False, "or", False, "or", True] my_list = [True,“和”,False,“或”,False,“ or”,True]

  1. I created a file temp.py 我创建了一个文件temp.py
  2. Entered all values in list of my_list in order space separated in temp.py 以temp.py分隔的顺序空间输入my_list列表中的所有值
  3. Executed temp.py 执行的temp.py
  4. Deleted temp.py 删除的temp.py

Kind of a hack ;) 有点黑客;)

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

相关问题 有没有一种简单的方法来检查对象是否在python中是可序列化的? - Is there an easy way to check if an object is JSON serializable in python? 有没有一种简单的方法来检查我的python 3.6脚本是否与python 2.7兼容? - Is there an easy way to check if my python 3.6 script is compatible with python 2.7? 有没有什么简单的方法可以检查 Python 文本文件中的重复项? - Is there any easy way to check for duplicates in a text file in Python? 有没有一种简单的方法可以使用 Python 中的断言来检查屏幕上打印的结果 - Is there an easy way to use asserts in Python to check for results printed on screen 如何使用 Python 以简单的方式检查非线性关系? - How to check in easy way non-linear relationships using Python? 有没有一种简单的方法可以在 Python 中编写这个? - Is there an easy way to write this in Python? 检查对象是否可打印的简便方法 - Easy way to check if object is printable 在Python中实现运算符优先级的一般方法是什么? - What is the general way to implement operators precedence in Python 在 Python 中使用 SQLCipher - 最简单的方法 - Using SQLCipher in Python - the easy way Python 数据类验证:一种简单的方法? - Python dataclass validation: an easy way?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM