python-3.x 如何将列表中的一组特定项目转换为所需项目

r3i60tvu  于 12个月前  发布在  Python
关注(0)|答案(3)|浏览(113)

基本上,我有这个清单。
[4097, add, 1, divide, blank, subtract, 3, floor, 1, add, 2, multiply, 8]
通过这个列表,我试图将[blank, subtract, 3]转换为[-3]
它将负数解释为具有带空左操作数的减法符号的等式。
有没有办法将合并[blank, subtract, 3]组合成[-3]?或者将[blank, add, 3]转换为[3]

wvt8vs2t

wvt8vs2t1#

您可以使用循环遍历列表,然后检查特定的关键字。

例如:

  • 不清楚blank代表什么,我用它作为表达式之间的分隔符。
def calc_list(lst):
    new_lst = [0]
    action_before = 'add'
    for i in lst:
        if i == 'blank':
            new_lst.append(0)
        elif i.isdigit():
            num = int(i)
            if action_before == 'add':
                new_lst[-1] += num
            elif action_before == 'subtract':
                new_lst[-1] -= num
            elif action_before == 'multiply':
                new_lst[-1] *= num
            elif action_before == 'divide':
                new_lst[-1] /= num
        else:
            action_before=i
    
    return new_lst
            

    
lst1 = ['blank', 'subtract', '3']
lst2 = ['4097', 'add', '1', 'divide', 'blank', 'subtract', '3','add', '1', 'add', '5', 'multiply', '8']
print(calc_list(lst2))
print(calc_list(lst1))

输出:

[-3]
[4098, 24]

编辑:

如果blank没有做任何事情,你可以简单地忽略它并继续前进:

def calc_list(lst):
    new_lst = [0]
    action_before = 'add'
    for i in lst:
        if i == 'blank':
            continue
            # new_lst.append(0)
        elif i.isdigit():
            num = int(i)
            if action_before == 'add':
                new_lst[-1] += num
            elif action_before == 'subtract':
                new_lst[-1] -= num
            elif action_before == 'multiply':
                new_lst[-1] *= num
            elif action_before == 'divide':
                new_lst[-1] /= num
        else:
            action_before=i
    
    return new_lst
            

    
lst1 = ['blank', 'subtract', '3']
lst2 = ['4097', 'add', '1', 'blank', 'subtract', '3','add', '1', 'add', '5', 'multiply', '8']
print(calc_list(lst2))
print(calc_list(lst1))

输出:

[32808]
[-3]
btqmn9zl

btqmn9zl2#

你将需要通过列表来删除你不想要的东西,并添加你想要的东西,没有自动的方法将三个项目替换为一个,但可以通过一个简单的函数来完成。

def replace_blank(blank_list):
for idx in range(0,len(blank_list)-3):
    if blank_list[idx] == 'blank':
        if blank_list[idx+1] == 'subtract':
            blank_list.pop(idx) #delete at that index
            blank_list.pop(idx)
            blank_list[idx] = '-' + blank_list[idx]
        elif blank_list[idx+1] == 'add':
            blank_list.pop(idx)
            blank_list.pop(idx)
        #.... any other operations i may want to add
            
return blank_list

4097“,”加“,”1“,”除“,”空“,”减“,”3“,”地板“,”1“,”加“,”2“,”乘“,”8“] print(replace_blank(list_bla))
由@nokla提出的编辑。这个函数的空间复杂度是O(1)。

0kjbasz6

0kjbasz63#

在处理这些示例时,我们假设:

  • 二元运算符是左结合的
  • 一元运算符是前缀通常,你还必须考虑二元运算符的优先级。一旦你这样做了,你就开始需要构建一个表达式树。为了构建树,解析器开始需要更多的状态变量来记住前一个字符串是什么,这样我们就知道用什么操作将它应用于当前操作数。
from math import ceil, floor

UNARY_OPERATORS=dict(
    subtract=lambda rhs: -rhs,
    ceil=lambda rhs: ceil(rhs),
    floor=lambda rhs: floor(rhs))
BINARY_OPERATORS = dict(
    add=lambda lhs, rhs: lhs + rhs,
    subtract=lambda lhs, rhs: lhs - rhs,
    multiply=lambda lhs, rhs: lhs * rhs,
    divide=lambda lhs, rhs: lhs / rhs)
BINARY_OPERATOR_PRECEDENCE=[['multiply', 'divide'], ['add','subtract']]

class EvaluatableExpression:
    def evaluate(self):
        return 0.0

class NumericExpression(EvaluatableExpression):
    def __init__(self, number):
        self.numeric_value = float(number)
 
    def evaluate(self):
        return self.numeric_value

class UnaryExpression(EvaluatableExpression):
    def __init__(self, oper_name, expression):
        self.operation = UNARY_OPERATORS[oper_name]
        self.expression = expression
 
    def evaluate(self):
        return self.operation(self.expression.evaluate())

class BinaryExpression(EvaluatableExpression):
     def __init__(self, oper, precedence, lhx, rhx):
         self.operation = BINARY_OPERATORS[oper] if isinstance(oper, str)\
             else oper
         self.precedence = precedence
         self.left_expression = lhx
         self.right_expression = rhx

     def evaluate(self):
         return self.operation(self.left_expression.evaluate(), self.right_expression.evaluate())

     @staticmethod
     def BuildBinaryExpression(existing_expression, oper_name, rhx):
         precedence = _estimate_precedence(oper_name)
         if not isinstance(existing_expression, BinaryExpression):
             # first binary expression, no need for precedence comparison
             return BinaryExpression(
                 oper_name,
                 precedence, 
                 existing_expression,
                 rhx)
         elif existing_expression.precedence < precedence or\
                 not isinstance(existing_expression, BinaryExpression):
             # create new top of tree
             return BinaryExpression(
                 oper_name,
                 precedence,
                 existing_expression,
                 rhx)
         else:
             # keep existing expression at top of tree
             existing_lhx = existing_expression.left_expression
             existing_rhx = existing_expression.right_expression
             new_child_expression = BinaryExpression(
                 oper_name,
                 precedence,
                 existing_rhx,
                 rhx)
             return BinaryExpression(
                 existing_expression.operation, 
                 existing_expression.precedence, 
                 existing_lhx, 
                 new_child_expression) 

def _estimate_precedence(oper_name):
     i=0
     for og in BINARY_OPERATOR_PRECEDENCE:
         if oper_name in og:
             return i
         else:
             i = i + 1

class ExpressionParser:
    def __init__(self):
        self.lhx = None
        self.next_unary_operator = None
        self.next_binary_operator = None

    def build_from_list(self, ar_list):
        for item in ar_list:
            assert(isinstance(item, str))
            assert(len(item.strip()) > 0)
            if self.looks_like_binary_operator(item):
                self.next_binary_operator = item
            elif self.looks_like_unary_operator(item):
                self.next_unary_operator = item
            elif self.looks_like_operand(item):
                rhx = NumericExpression(item)
                self._handle_binary_expression(rhx)

    def looks_like_binary_operator(self, item):
        return  item in BINARY_OPERATORS and\
             self.next_binary_operator is None and self.lhx is not None

    def looks_like_unary_operator(self, item):
        return item in UNARY_OPERATORS and self.next_unary_operator is None

    def looks_like_operand(self, item):
         return item[0].isdigit()

    def _handle_binary_expression(self, rhx):
        if self.next_unary_operator:
            # apply unary operator
            rhx = UnaryExpression(self.next_unary_operator, rhx)
            self.next_unary_operator = None

         # try binary operator after unary one
        if self.next_binary_operator:
            self.lhx = BinaryExpression.BuildBinaryExpression(
                 self.lhx,
                 self.next_binary_operator,
                 rhx)
            self.next_binary_operator = None
        if self.lhx is None:
            self.lhx = rhx

def iterate_arithmetic_list(ar_list):
    parser = ExpressionParser()
    parser.build_from_list(ar_list)

    return parser.lhx.evaluate()

相关问题