微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

减少if / elif的使用

如何解决减少if / elif的使用

有什么方法可以减少执行清单/字典/元组的这段代码中if和elif的数量

cod =
    ['menu'],['dimension 1"'],['dimension 2”'],['dimension 3”'],['dimension 4'],['dimension 5'],['dimension 6'],['dimension 7'],['dimension 8'],['dimension 9'],['dimension 10']
]
return cod

    if choice == 1:
    quantify = float(input(('Quantify: ')))
    if 0 < quantify <= 6:
        print('± 0,1mm')
    elif 6 < quantify <= 30:
        print('± 0,2mm')
    elif 30 < quantify <= 120:
        print('± 0,3mm')
    elif 120 < quantify <= 400:
        print('± 0,5mm')
    elif 400 < quantify <= 1000:
        print('± 0,8mm')
    elif 1000 < quantify <= 2000:
        print('± 1,2mm')
    elif 2000 < quantify <= 4000:
        print('± 2mm')
    else:
        print('<<< Min = 0,5mm | Max = 4000mm >>>')
elif choice == 2:
    quantify = float(input(('Quantify: ')))
    if 0 < quantify <= 3:
        print('± 0,2mm')
    elif 3 < quantify <= 6:
        print('± 0,5mm')
    elif 6 < quantify:
        print('± 1mm')
    else:
        print('<<< Min = 0,5mm | Max = ∞ >>>')

*我不得不更改某些内容以使其可读性,因为它是葡萄牙语和其他一些功能的语言。

谢谢, soldcarvalho

解决方法

使用字典和列表是正确的想法。这就是我简化您的代码以不使用一堆if else语句的方式。

from collections import namedtuple

tolerance = namedtuple( 'tolerance',['lower_bound','upper_bound','tolerance'] )

tolerances = {
    '1': [
        tolerance(0,6,'± 0,1mm'),tolerance(6,30,2mm'),tolerance(30,120,3mm'),tolerance(120,400,5mm'),tolerance(400,1000,8mm'),tolerance(1000,2000,'± 1,tolerance(2000,4000,'± 2mm')
    ],'2': [
        tolerance(0,3,tolerance(3,'inf','± 1mm'),]
}

def get_tolerance(quantify,choice):
    for t in tolerances[choice]:
        if t.lower_bound <= quantify <= t.upper_bound:
            return t.tolerance

    # if we didn't find a matching tolerance,raise an error
    min_tolerance = min( t.lower_bound for t in tolerances[choice] )
    max_tolerance = max( t.lower_bound for t in tolerances[choice] )
    raise ValueError(f'<<< Min = {min_tolerance} | Max = {max_tolerance} >>>')


choice = input('Choice: ')
while choice not in tolerances:
    print('Invalid choice. Choice must be one of the following:',','.join(tolerances.keys()))
    choice = input('Choice: ')

quantify = float(input('Quantify: '))
print('Tolerance is:',get_tolerance(quantify,choice))

我选择使用named tuple来存储公差信息而不是列表。如果您从未听说过命名元组,则它们的工作方式是指定一些字段(例如,lower_bound,upper_bound,tolerance),然后返回在我们的情况下可以用来创建{命名元组。当我们使用tolerance创建一个命名元组时,例如tolerance,那么我们就可以执行t = tolerance(0,1mm')来获得下界,t.lower_bound来获得上界和t.upper_bound。当您需要存储固定数量的项目时,使用这样的命名元组而不是列表,可以使代码更易于阅读。

,

替换包含严格相等比较的if...elif链非常简单。但是,当您有范围时,字典不是正确的解决方案。相反,您将需要一个自定义数据结构,该结构将每个范围的开始和结束与if语句进行比较。然后,您可以使用for循环遍历范围列表中的所有范围。

,

有两种方法可以做到这一点。注意其他人也发布了类似的内容:)

""" SO QA """

import bisect


class Tolerance:
    def __init__(self,lower_limit,text):
        self._lower_limit = lower_limit
        self._text = text

    def __eq__(self,other):
        return self.lower_limit == other.lower_limit

    def __lt__(self,other):
        return self.lower_limit < other.lower_limit

    def __gt__(self,other):
        return self.lower_limit > other.lower_limit

    def __str__(self):
        return '{:4d} {}'.format(self.lower_limit,self.text)

    @property
    def lower_limit(self):
        return self._lower_limit

    @property
    def text(self):
        return self._text

    @staticmethod
    def get(tolerance_list,value):
        if isinstance(value,int):
            value = Tolerance(value,"")
        if isinstance(value,Tolerance):
            idx = bisect.bisect_right(tolerance_list,value)
            if idx:
                return tolerance_list[idx-1]
            raise ValueError('value {} is out of range'.format(value))
        raise TypeError('unexpected type: {}'.format(type(value)))


_TOLERANCES = [
    Tolerance(   0,Tolerance(   6,Tolerance(  30,Tolerance( 120,Tolerance( 400,Tolerance(1000,Tolerance(2000,'± 2,0mm'),Tolerance(4000,'over range'),]


def get_tolerance_using_dict(value):
    """
    Based on the value,get the tolerance entry.
    :param value: The integer value that is within the expected range.
    :returns:     A entry dict {lower_limit: value,text: ""}.
    """
    tolerances = [
        {'lower_limit':    0,'text': '± 0,1mm'},{'lower_limit':    6,2mm'},{'lower_limit':   30,3mm'},{'lower_limit':  120,5mm'},{'lower_limit':  400,8mm'},{'lower_limit': 1000,'text': '± 1,{'lower_limit': 2000,'text': '± 2,0mm'},{'lower_limit': 4000,'text': 'over range'},]

    prev_entry = None
    for entry in tolerances:
        if entry['lower_limit'] <= value:
            prev_entry = entry
        else:
            return prev_entry
    return tolerances[len(tolerances) - 1]
    # Perhaps a better way to handle the range error:
    # raise ValueError('value is out of range'.format(value))


def main():
    """ Test the stuff """
    values = [0,1,2,4,5,7,8,29,100,119,121,1999,2001,3999,4001]

    print('using class:')
    for value in values:
        print('{:3} : {}'.format(value,Tolerance.get(_TOLERANCES,value)))

    print('using dict:')
    for value in values:
        print('{:3} : {}'.format(value,get_tolerance_using_dict(value)))



if __name__ == "__main__":
    main()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。