嵌套If替换Python



我得到了这段代码,需要找到一种更可读、更实用的方法来编写它,这个项目使用python 3.6

level_buy = 62
level=0
a1= range(1,10)
a2= range(12,16)
a3= range(18,29)
a4= range(34,46)
a5= range(54,63)
a6= range(73,85)
b1= range(10,12)
b2= range(16,18)
b3= range(29,34)
b4= range(46,54)
b5= range(63,73)
if recomendation=='buy':
if level_buy in a1:
level=a2[0]
if level_buy in b1:
level=b2[0]
if level_buy in a2:
level=a3[0]
if level_buy in b2:
level=b3[0]
if level_buy in a3:
level=a4[0]
if level_buy in b3:
level=b4[0]
if level_buy in a4:
level=a5[0]
if level_buy in b4:
level=b5[0]
if level_buy in a5:
level=a6[0]
if level_buy in b5:
level=85
if level_buy in a6:
level=85

如果level_buy在其中一个定义的范围内,则返回该值,设置level=下一个范围中的第一个数字。示例:level_buy=62,如果我调用level,应该返回73

提前感谢

我相信您可以用for循环来替换您的一系列if语句,以迭代您的范围。

ranges = (a1, b1, a2, b2, a3, b3, a4, b4, a5, b5)
if recomendation == 'buy':
for i, ab in enumerate(ranges[:-1]):
if level_buy in ab:
level = ranges[i+1][0]
break
else:
level=85
print(level)

您可以将范围保留在一个列表中,而不是有许多单独的变量:

ranges = [
range(1,10),
range(12,16),
range(18,29),
...
]

然后你可以迭代列表:

for pos, r in enumerate(ranges):
if level_buy in r:
level = ranges[pos+1][0]

如果您不希望最后一个a范围链接到第一个b范围,您可以保留两个列表。

假设:没有任何范围重叠,并且级别始终是下一个连续范围的上限。方法是过滤掉较低的级别,然后跳过一个级别以获得正确的数字。

level_buy = 62
thresholds = [1,10,12,16,18,29,34,46,54,63,73,85]
selection = [t for t in thresholds if level_buy < t]
level = selection[1] if len(selection) > 1 else 85

您错过了声明recommendation。但如果你想保持与你发布的逻辑相似的逻辑,这里有一个替代脚本的方法:

from itertools import chain
recommendation = "buy"
level_buy = 62
level = 0
a1 = range(1, 10)
a2 = range(12, 16)
a3 = range(18, 29)
a4 = range(34, 46)
a5 = range(54, 63)
a6 = range(73, 85)
b1 = range(10, 12)
b2 = range(16, 18)
b3 = range(29, 34)
b4 = range(46, 54)
b5 = range(63, 73)
a_ranges = [a1, a2, a3, a4, a5, a6]
b_ranges = [b1, b2, b3, b4, b5]
combined_ranges = chain.from_iterable(zip(a_ranges, b_ranges))
if recommendation == "buy":
for range_ in combined_ranges:
if level_buy in range_:
level = range_[0]
break
print(level)

如果您多次调用此函数,并且两者都没有太多的范围要设置,并且愿意拥有查找表所需的前期成本和内存,则可以预处理此函数:

from itertools import chain
level_sets = [(range(1,10), 12),
(range(12,16), 18),
(range(18,29), 34),
(range(34,46), 54),
(range(54,63), 73),
(range(73,85), 85),
(range(10,12), 16),
(range(16,18), 29),
(range(29,34), 46),
(range(46,54), 63),
(range(63,73), 85)]
levels = {l: s for l, s in chain(*([(k, v) for k in r] for r, v in level_sets))}
...
for buy in recommendation_list: 
level = levels.get(level_buy)

这基本上意味着,对于每个整数,你都有它将指向的某个级别。这样做的好处是,每次你需要获得级别购买的级别时,这都是一个O(1(运算-因此,如果你有大量的建议要做,它将有一点前期成本(构建查找表(,然后只有很少的增量成本(查找级别购买(。这与没有前期成本和每次O(n(成本形成对比,其中n是您拥有的范围数。

最新更新