关于python:压缩几个elif语句

compressing several elif statements

我写了一些代码来找出两个时间序列之间的差异有多接近,并通过从最近的实际变化中找到与预期差异位置的距离,并根据距离来分配分数来实现这一点。

在这段代码中,我有如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
nearest_change = np.abs(actual_changes[actual_changes == change].index - time).min()

minutes_off = nearest_change.seconds/60
if minutes_off < 15:
  sum += 1
elif minutes_off < 30:
  sum += .8
elif minutes_off < 45:
  sum += .6
elif minutes_off < 60:
  sum += .4
elif minutes_off < 65:
  sum += .2

return sum / count

有没有一种更简洁的方法来达到这种得分?


您可以循环通过每个阈值,每次增加0.2。

1
2
3
4
5
6
thresholds = [15, 30, 45, 60, 65]
for time_diff in thresholds:
    if minutes_off < time_diff:
        sum += .2
    else:
        break

根据需要的数量,动态创建阈值列表可能值得。


如果您的映射是离散的,并且不能用简单的公式描述,那么您可以使用OrderedDict创建它们:

1
2
3
4
5
6
from collections import OrderedDict
d = OrderedDict([(15,1),(30,.8),(45,.6),(60,.4),(65,.2)])
for key,value in d.items():
    if minutes_off < key:
            s += value
            break

注意,我将sum重命名为s,以避免与python内置函数冲突。


是的,有。我想这一个更好,尽管它使用更多的代码来实现相同的效果,并且速度较慢。但它确实避免了重复。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class ScoreAccessDict(dict):
    def __init__(self, *args, f, **kwargs):
        self.f = f
        super().__init__(*args, **kwargs)

    def __getitem__(self, item):
        iterator = iter(self.keys())

        try:
            best = next(iterator)
        except StopIteration:
            raise KeyError(item)

        for k in iterator:
            if self.f(best, item) < self.f(k, item):
                best = k

        return super().__getitem__(best)

    def get(self, key, default=None):
        try:
            return self[key]
        except KeyError:
            return default

并使用它:

1
2
3
4
5
6
7
nearest_change = np.abs(actual_changes[actual_changes == change].index - time).min()

minutes_off = nearest_change.seconds / 60  # spaces between operands and the operator

d = ScoreAccessDict({15: 1, 30: 0.8, 45: 0.6, 60: 0.4, 65: 0.2, float('inf'): 0}, f = lambda x, y: x if x < y else -x)

return s + d[minutes_off]  # sum shouldn't be shadowed

但是从您的代码判断,所添加的值应该使用连续函数来计算。这将是最为Python式的方式。