缩短许多if-elif?字典中的函数?

时间:2021-07-01 04:19:38

标签: python python-3.x

当我在比较温度以确定温度的形容词时,我最终得到了许多丑陋的 if-elif,我想我可以在字典的列表中查找温度值,它的键将是对应的形容词温度:

def deternmine_temp(temp):

temps = {
    'FREEZING'  : [i for i in range(-20, 0)],
    'very cold' : [i for i in range(0, 6)],
    'cold'      : [i for i in range(6, 11)],
    'chilly'    : [i for i in range(11, 16)],
    'cool'      : [i for i in range(16, 21)],
    'warm'      : [i for i in range(21, 26)],
    'hot'       : [i for i in range(26, 31)],
    'very hot'  : [i for i in range(31, 36)],
    'dangerously hot' : [i for i in range(36, 40)],
    'extremely dangerously hot': [i for i in range(41, 46)]
}

temp = int(temp.replace('°', '').strip())

for word, values in temps.items():
    if temp in values:
        return word

这比 7+ if-elif 好很多,但我认为它不是很有效,特别是如果 temps 有更多数据(例如,如果我有一个更窄的值范围对应于一个形容词).

有什么方法可以提高效率?也许字典中有一些功能?以上真的是我能想到的最好的了。

3 个答案:

答案 0 :(得分:1)

您需要以某种方式存储范围,并且由于范围没有相同的间隔,因此您无法真正缩短字典初始化。您可以将字典创建提取到一个函数中,但是您仍然需要根据选项调用它的次数。

然而,您可以从字典中删除列表理解并将循环替换为 next

def deternmine_temp(temp):
    temps = {
            'FREEZING': range(-20, 0),
            'very cold': range(0, 6),
            'cold': range(6, 11),
            'chilly': range(11, 16),
            'cool': range(16, 21),
            'warm': range(21, 26),
            'hot': range(26, 31),
            'very hot': range(31, 36),
            'dangerously hot': range(36, 40),
            'extremely dangerously hot': range(41, 46)
            }

    temp = int(temp.replace('°', '').strip())
    return next((word for word, values in temps.items() if temp in values), None)

答案 1 :(得分:0)

如果您决定将温度表示为浮点数,则您的代码通常无法运行。为确保您的代码适用于非整数温度(以防万一),请将范围表示为最小-最大值对并使用显式比较:

temps = {
    'FREEZING'  : (-20, 0),
    'very cold' : (0, 6),
    ....
}

for word, values in temps.items():
    if values[0] <= temp < values[1]:
        return word

您也可以使用元组列表,因为您不使用特定于字典的功能:

temps = [
    ('FREEZING', -20, 0),
    ('very cold', 0, 6),
    ....
]

for word, value1, value2 in temps:
    if value1 <= temp < values2:
        return word

最后,为了一致性,您可以只定义范围的上边界(同时也是下一个范围的下边界):

temps = [
    ('FREEZING', 0),
    ('very cold', 6),
    ....
    ('extremely dangerously hot': float('inf'))
]

for word, value in temps:
    if temp < value:
        return word

答案 2 :(得分:0)

This 最接近我想要的。

def switch(x):
    return {
            -20<x<=2: 'FREEZING',
            2<x<=5: 'very cold',
            5<x<=10: 'cold',
            10<x<=15: 'chilly',
            15<x<=22: 'cool',
            22<x<=25: 'warm',
            25<x<=30: 'hot',
            30<x<=33: 'very hot',
            33<x<=35: 'extremely hot',
            35<x<=40: 'dangerously hot'
            }[1]

print(switch(40))

输出:

dangerously hot