【问题标题】:Pythonic way of closing range after last iteration上次迭代后关闭范围的 Pythonic 方式
【发布时间】:2016-11-17 11:20:25
【问题描述】:

我有一个代码样式问题,我正在寻找我在下面写的内容的 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)

【问题讨论】:

  • 需要审查/改进的工作代码更适合codereview

标签: python python-3.x iteration


【解决方案1】:

我找到了一个很好的方法:

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 值,并在使用前将其与您的函数进行比较。

【讨论】:

    【解决方案2】:

    简单的方法是编辑内部条件:

        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)? (这取决于您在循环中执行的其他操作)

    【讨论】:

    • 您遇到了一个错误。你需要比较i == input_length-1,但是你不能只做results.append((start, i))
    • @Rawing 你说得对,我解决了这个问题,虽然我不确定这对他来说是否是一个好的解决方案。
    • hmm 这个解决方案的问题在于,最后一个元素满足条件的序列和不导致相同范围的序列。
    • @caenyon 是的 :( 你考虑了我帖子末尾的建议吗?
    • 是的,我之前考虑过...问题是,当在循环中使用 i 作为长度 input_length 列表的索引时,这会带来问题。
    猜你喜欢
    • 2019-10-18
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 2010-11-21
    • 2011-10-28
    • 2011-03-25
    • 1970-01-01
    相关资源
    最近更新 更多