【问题标题】:What is the pythonic way to to resume a loop within a loop在循环中恢复循环的pythonic方法是什么
【发布时间】:2016-06-16 20:39:12
【问题描述】:

我有一个 python 2.7 应用程序,我偶尔会中断。

我正在处理一个非常大的数据文件。为了处理内存限制,我将数据文件划分为由 x 和 y 分量标识的网格。每个网格都是独立处理的。

处理需要很长时间,所以偶尔需要在某个时间点停止处理。理想情况下,我想更新 y_start 和 x_start 并在我离开的地方恢复应用程序(不处理已经处理的网格)。

主要动作发生在嵌套的for循环中:

x_start=0.0
x_step=0.05
x_size=10.0
y_start=0.0
y_step=0.05
y_size=10.0

x_ranges = zip(np.arange(x_start,x_size,x_step), np.arange(x_step+x_start,x_size+x_step,x_step))

y_ranges = zip(np.arange(0.0,y_size,y_step), np.arange(y_step,y_size+y_step,y_step))


for x_min,x_max in x_ranges:
    for y_min,y_max in y_ranges:

        doAction()

在上面的代码中,我处理了 x_start。 y_start 应该只用于当 x_min = x_start 时。对于 x 的所有其他值,它应该从 0.0 开始。

这是我提出的解决方案。有没有更好,更pythonic的方式:

y_ranges_resume = zip(np.arange(y_start,y_size,y_step),np.arange(y_start+y_step,y_size+y_step,y_step)

for x_min,x_max in x_ranges:
    if x_min == x_start:     
        for y_min,y_max in y_ranges_resume:
            doAction()
    else:
        for y_min,y_max in y_ranges:
            doAction()

【问题讨论】:

  • 我认为你应该解释你想要实现的目标,我相信你的代码可以做更多的事情,而不是 for 循环 :)
  • 好点。我会补充细节。
  • DRY (Don't Repeat Yourself),你可以在你的 for 表达式中使用三元运算符,例如:for y_min, y_max in y_ranges_resume if x_min == x_start else y_ranges:
  • 谢谢。这正是我想要的。
  • 否则你可以使用while loop

标签: python python-2.7 for-loop resume


【解决方案1】:

我不确定是否有更 Pythonic 的方式,但你可以这样重写它(真的可以用任何语言):

y_ranges_resume = zip(np.arange(y_start,y_size,y_step),np.arange(y_start+y_step,y_size+y_step,y_step)

for x_min,x_max in x_ranges:
    y_ranges_used = y_ranges
    if x_min == x_start:     
        y_ranges_used = y_ranges_resume

    for y_min,y_max in y_ranges_used:
        doAction()

至少内循环只写一次。

或者你可以使用三元,但我的错误是更容易阅读而不是更小的代码。但是为了完整起见,你可以这样写同样的东西:

y_ranges_resume = zip(np.arange(y_start,y_size,y_step),np.arange(y_start+y_step,y_size+y_step,y_step)

for x_min,x_max in x_ranges:
    for y_min, y_max in y_ranges_resume if x_min == x_start else y_ranges:
        doAction()

【讨论】:

    【解决方案2】:

    您可以尝试列表理解:

    [[doAction() for y_min,y_max in y_ranges_resume] if x_min == x_start else [doAction() for y_min,y_max in y_ranges] for x_min,xmax in x_ranges]
    

    或者您可以使用 lambda 函数来简化条件

    correct_y_range = lambda x : y_ranges_resume if x == x_start else y_ranges
    [[doAction() for y_min,y_max in correct_y_range(x_min)] for x_min,x_max in x_ranges]
    

    lambda 函数的另一个选项(为了更好的可读性)

    correct_y_range = lambda x : y_ranges_resume if x == x_start else y_ranges
    for x_min,x_max in x_ranges:
        for y_min, y_max in correct_y_range(x_min):
            doAction()
    

    【讨论】:

    • 它更像 Python :-)。我试图避免使用 doAction() 两次,括号使代码更难阅读。
    • 我再添加一个和Aaron的类似的
    • 谢谢。这会很有帮助。
    猜你喜欢
    • 2019-07-19
    • 1970-01-01
    • 2018-04-28
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    • 2017-08-17
    相关资源
    最近更新 更多