循环遍历嵌套列表并跟踪它

时间:2017-07-09 21:44:48

标签: python python-3.x python-3.6

实施例

input:  [1, '+', [4, '*', [3, '*', 7]], '/', 2]  
output:  43

input:  [[1, '+', 3], '*', [2, '+', 4]] 
output:  24

嵌套列表的数量未知

我不确定如何处理这个问题。我已查找其他循环嵌套列表帖子(iterate python nested lists efficiently& Python - Iterating through list of list)但在这种情况下它们确实不起作用,因为括号中的操作顺序不同。

我曾经想过使用递归但我不知道如果它有大量的嵌套循环我将如何编码它我不知道如何跟踪所有内容并找到最深的名单。
感谢

编辑:哎呀,抱歉,没有说清楚。试着基本上根据列表包含的内容来做数学表达式。它可能包含* + - /和%,我们必须根据操作顺序执行此操作。

EDIT2:如何将操作顺序和括号优先权应用于这样的事情?

import operator
ops = {'+': operator.add, '-': operator.sub, '*': operator.mul, '/': 
operator.truediv, '%': operator.mod}

def do_math(equation):
    if isinstance(equation, list):
        op = ops[equation[1]]
        return op(do_math(equation[0]), do_math(equation[2]))
    else:
        return equation

print (do_math([1, '+', [4, '*', [3, '*', 7]], '/', 2]))

1 个答案:

答案 0 :(得分:1)

您可以使用递归函数,该函数在找到的下一个运算符具有较低优先级时仍保持执行堆栈操作。只要运算符具有越来越高的优先级,它就会将这些与左侧值一起添加到堆栈中。

使用命名元组和运算符函数不是绝对必需的,但会使代码更具可读性:

from operator import mul, truediv, mod, sub, add
from collections import namedtuple

Oper = namedtuple('Oper', 'f, prio')
HalfExpr = namedtuple('HalfExpr', 'value, oper')
ops = {
    "*": Oper(f=mul,     prio=1),
    "/": Oper(f=truediv, prio=1),
    "%": Oper(f=mod,     prio=1),
    "-": Oper(f=sub,     prio=2),
    "+": Oper(f=add,     prio=2)
}

def calc(expr):
    if not isinstance(expr, list):
        return expr
    stack = []
    for i in range(0, len(expr), 2):
        oper = ops[expr[i+1]] if i+1 < len(expr) else ops['+'] 
        value = calc(expr[i])
        while len(stack) and stack[-1].oper.prio <= oper.prio:
            a = stack.pop()
            value = a.oper.f(a.value, value)
        stack.append(HalfExpr(value, oper))
    return stack[0].value

print(calc([1, '+', [4, '*', [3, '+', 7]], '/', 2]))

repl.it

上查看它