Pythonic方式在最后一次迭代后关闭范围

3
我有一个代码风格问题,并且正在寻求一个pythonic实现我下面的内容。
发布的(简化的)代码遍历序列并返回范围。每个范围都以特定条件开始和结束。范围不能重叠。我使用变量 “active” 来跟踪是否已经找到了范围的起始位置。如果在序列结束时活动范围尚未关闭,则应添加该范围(以 input_length 作为结束索引)。
下面的代码按预期工作,但我不喜欢事实上两次编写将范围附加到结果列表的代码。在我的真正问题中,这个块要长得多,我不想在 for 循环后再写一次。
你有什么建议如何改进这个问题吗?
谢谢!
input_length = 100
results = []

active = False
start = None
for i in range(input_length):
    condition = i % 9 == 0
    if not active and condition:
        active = True
        start = i

    condition2 = i % 13 == 0
    if active and condition2:
        active = False
        # do some additional calculations...
        results.append((start, i))

if active:
    # do some additional calculations...
    results.append((start, input_length))

print(active)
print(results)

4
需要审查/改进的可工作代码更适合在codereview上进行。 - syntonym
2个回答

1
简单的方法是编辑内部条件:
    condition2 = i % 13 == 0
    if active and (condition2 or i == input_length-1))
        active = False
        # do some additional calculations...
        results.append((start, i if condition2 else i + 1))

并移除外部。

如果你想避免使用 i if condition2 else i + 1,也许可以在 range(input_length + 1) 上迭代?(这取决于循环中的其他操作)


1
你有一个 off-by-one 错误。你需要比较 i == input_length-1,但是你不能只是简单地执行 results.append((start, i)) - Aran-Fey
@Rawing 你说得对,我已经修复了,不过我现在不确定那是否是一个好的解决方案。 - Ohad Eytan
这个解决方案的问题在于,最后一个元素满足条件和不满足条件的序列会导致相同的范围。 - Felix
@caenyon 是的 :( 你考虑一下我帖子最后的建议了吗? - Ohad Eytan
是的,我之前考虑过这个问题...... 问题在于,在循环中使用 i 作为长度为 input_length 的列表的索引时会出现问题。 - Felix

0
我找到了一个不错的方法来做到这一点:
import itertools as it

il = 100
results = []
def fun1():
    active = False
    start = None
    for i in range(il):
        condition = i % 9 == 0
        if not active and condition:
            active = True
            start = i
        condition2 = i % 13 == 0
        if active and condition2:
            active = False
            # do some additional calculations...
            results.append((start, i))
    if active:
        # do some additional calculations...
        results.append((start, il))
    return results

def fun2():
    a=b=0
    while b<il:
        yield (a,b)
        b=b+13
        a=a+9
        while a<=b-13:
            a=a+9
    if a<il:
        yield (a,il)

print fun1()
print
print [(a,b) for (a,b) in fun2()]

请在使用之前检查代码中不同的il值,并将其与您的函数进行比较。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接