Py学习  »  Python

嵌套式If可选Python

CodeAgainst • 3 年前 • 1273 次点击  

我得到了这段代码,需要找到一种更具可读性和功能性的方法来编写它,这个项目使用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

提前谢谢

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/128212
 
1273 次点击  
文章 [ 5 ]  |  最新文章 3 年前
Nathaniel Ford
Reply   •   1 楼
Nathaniel Ford    3 年前

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

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 是您拥有的范围数。

irahorecka
Reply   •   2 楼
irahorecka    3 年前

你没申报 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)
Olav Aga
Reply   •   3 楼
Olav Aga    3 年前

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

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
John Gordon
Reply   •   4 楼
John Gordon    3 年前

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

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 范围,你也许可以保留两个列表。

defladamouse
Reply   •   5 楼
defladamouse    3 年前

我相信你可以取代你的系列产品 if 带有 for 循环在你的范围内迭代。

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)