为什么我的'while'循环没有返回值?

时间:2014-09-30 04:07:27

标签: python

我的任务是以字符串的形式接受数学运算并将答案作为整数返回。操作顺序也被忽略,数学运算必须从左到右解决。

我的代码可能更短/更简单,但这就是我想出来的。我的策略是遍历字符串中的每个字符,直到我遇到一个运算符(+, - ,x,/)。然后,运算符之前的数字串变为整数。运算符存储为变量c,以便可以使用当前数字和遇到的下一个数字(c = 1表示加法等)来完成操作。

当我运行程序时,它应该打印变量total,但不打印任何内容。 return语句退出当前if语句,还是退出while循环?问题还有别的吗?

def compute(e):
    a=0 #starting index used to check specific characters in string
    b=0 #to keep track of index after last operator
    l=len(e) #length of e to use for while loop
    st=""
    total=0 #result of all previous calculations
    count=0 #keeps track of number of operators passed
    c=0 #Used to keep track of what operator was last passed
        #c=1 is addition
        #c=2 is subtraction
        #c=3 is multiplication
        #c=4 is division
    while l>0:
        if e[a].isdigit():
            return
        elif e[a]=="+" or e[a]=="-" or e[a]=="x" or e[a]=="/": #When an operator is detected in string
            st=e[b:a] #To combine all numbers between two operators into one string
            count=count+1 #to keep track of number of operators passed
            b=a+1 #now b is the index after the last operator
            if count==1: #This is the first operator encountered in string
                total=int(st) #The string is stored as total because this is the first integer stored
            else:
                num=int(st) #The string of numbers is stored as num instead of total
            if count==1: #This means this is the first operator and there should not be an operation done yet
                return
            elif c==1:
                total=total+num
            elif c==2:
                total=total-num
            elif c==3:
                total=total*num
            elif c==4:
                total=total/num
            if e[a]=="+":
                c=1
            elif e[a]=="-":
                c=2
            elif e[a]=="x":
                c=3
            elif e[a]=="/":
                c=4
        else:
            return None
        a=a+1
        l=l-1
    print(total)

compute("22-11x4")
input("Wait")

3 个答案:

答案 0 :(得分:1)

试试这段代码:

def compute(e):
    l=len(e)
    seperate=[]
    indexf=0
    indexl=0
    count=1
    total=0
    num=0

    for i in range(0,l):
        if (e[i].isdigit()):
            indexl=indexl+1
        else:
            num=e[indexf:indexl]
            indexf=indexl+1
            indexl=indexf
            seperate.append(num)
            seperate.append(e[i])
    num=e[indexf:indexl+1]
    seperate.append(num)

    l=len(seperate)

    for i in range(0,l):
        if (count==1):
            total=int(seperate[i])
            count=count+1
        else:
            if (not(seperate[i].isdigit())):
                if (seperate[i]=="+"):
                    total=total+int(seperate[i+1])
                elif (seperate[i]=="-"):
                    total=total-int(seperate[i+1])
                elif (seperate[i]=="*") or (seperate[i]=="X")or(seperate[i]=="x"):
                    total=total*int(seperate[i+1])
                elif (seperate[i]=="/"):
                    total=total/int(seperate[i+1])

    print("Resault is %d ,Have a good time" %(total))

st=input("Please insert your expression :")
compute(st)

答案 1 :(得分:0)

这是一个例子,我在一个基础问题的不同方法上拼凑在一起。我的'calculate'函数将字符串打破了“不是数字的东西”(re.split(r'(\D+)', string)),存储拆分的东西);然后我们走结果列表(for item in re.split(r'(\D+)', string):)。

如果它是一堆连续数字(if re.match(r'\d+', item):),我们会将其附加到collections.deque();如果它是空格(if re.match(r'\s+', item):),我们会扔掉它(continue)。否则,我们假设它是一个运算符,它只是附加到operators列表(为x制作的特殊情况),我们将其转换为* - 这对我来说纯粹是装饰性的)。

我定义了一个lambdas字典(doop,用于'do operations'),其中键是我支持的运算符,表达式是要执行的数学运算。现在剩下的就是遍历operators列表(for op in operators),找到该运算符的正确lambda(doop[op]()),并调用它 - 传递两个“top”值在operands deque(operands.popleft())上,将结果放回到列表顶部,以便下一个operator消费(operands.appendleft())。

我的简单示例无法处理很多边缘情况,并且它显然不知道运算符优先级(但是你说它不应该尝试应用它)。我只是想给你一个替代的方法,可能会把你的想法放在一条不同的道路上 - 也许比所有的if / elsif / else更容易维护。

import collections
import re

doop = {
    '+': lambda x,y: x+y,
    '*': lambda x,y: x*y,
    '-': lambda x,y: x-y,
    '/': lambda x,y: x//y
}

def calculate(string):
    operands = collections.deque()
    operators = []
    for item in re.split(r'(\D+)', string):
        if re.match(r'\d+', item):
            operands.append(int(item))
            continue
        if re.match(r'\s+', item):
            continue
        else:
            if item == 'x':
                item = '*' # *shrug*
            operators.append(item)
    for op in operators:
        operands.appendleft(doop[op](operands.popleft(),operands.popleft()))
    result = operands.pop()
    print("Calculated %s to be %s" % (string, result))
    return result


strings = ["15+2*3-7", "22-11x4"]
for string in strings:
    calculate(string)

答案 2 :(得分:-1)

我将指出一些可以帮助您解决此代码的问题。首先,像许多人已经指出return语句突破了函数,因此不应该在while循环中使用。如果需要,请将其替换为breakcontinue。其次,这段代码:

 if e[a].isdigit():
        return

我觉得没有必要。因为无论e[a]的值是什么,循环都会继续,并且值会不断累积在total变量中。

第三,如果我没有错,你可以将操作符分配给整数。虽然可以省略,但在更新c变量之后进行检查以将值分配给total时,您在分配它们之前使用这些整数代码执行计算。所以我想一旦你输入elif块,你检查当前字符是否是操作符,你的第一步应该是为c分配适当的值并进行必要的计算。

类似的东西:

 elif e[a]=="+" or e[a]=="-" or e[a]=="x" or e[a]=="/": #When an operator is detected in string
        st=e[b:a] #To combine all numbers between two operators into one string
        count=count+1 #to keep track of number of operators passed
        b=a+1 #now b is the index after the last operator
        if count==1: #This is the first operator encountered in string
            total=int(st) #The string is stored as total because this is the first integer stored
        else:
            num=int(st) #The string of numbers is stored as num instead of total

        #Assign operator values
        if e[a]=="+":
            c=1
        elif e[a]=="-":
            c=2
        elif e[a]=="x":
            c=3
        elif e[a]=="/":
            c=4

        #Perform arithmetic operation
        if count !=1: #Not the first operator, we can accumulate the values
          if c==1:
            total=total+num
          elif c==2:
            total=total-num
          elif c==3:
            total=total*num
          elif c==4:
            total=total/num

我稍稍重组了你的elif块。我已经废除了return语句,只是在我们进行计算之前执行了检查。实际上,这是您应该执行的唯一检查,以便ifelse语句可以删除return,并且只需一个if语句就可以安全地替换它。我希望它能让你清楚地了解你的代码并让你开始朝着正确的方向前进。