交替控制流与条件或预处理器

时间:2016-09-04 19:18:07

标签: python

鉴于此代码:

for i in range(5):
  foo(i)
  bar(i)

我想在两个print行之间添加一些代码,这样我就可以将循环分成两个,但只有当某个标志为真时,即:

for i in range(5):
  foo(i)

if debug: {
  continue
for i in range(5):
}

  bar(i)

不幸的是这不是有效的python。有没有办法我可以做到这一点,而无需手动重写循环:

if debug:
  for i in range(5):
    foo(i)
  for i in range(5):
    bar(i)
else:
  for i in range(5):
    foo(i)
    bar(i)

3 个答案:

答案 0 :(得分:0)

如果我理解正确,你想要在第一种情况下批量调用函数(所有可能的args用于第一个函数,然后所有可能的args用于第二个函数等),并且批量参数在第二种情况下(所以所有函数用于第一个) arg,然后是第二个arg的所有函数等。)

我要说你必须明确地这样做:

def foo(i):
    print("foo", i)

def bar(i):
    print("bar", i)

def stretch(seq, n):
    """stretch([1,2,3], 3) -> [1,1,1,2,2,2,3,3,3], lazy generator"""
    for o in seq:
        for _ in range(n):
            yield o


def run(args, functions, mode):
    if mode:
        my_args = list(stretch(args, len(functions)))
        my_functions = functions * len(args)
    else:
        my_args = args * len(functions)
        my_functions = list(stretch(functions, len(args)))
    for f, a in zip(my_functions, my_args):
        f(a)

调用:

run(list(range(5)), [foo, bar], 0)

输出:

foo 0
foo 1
foo 2
foo 3
foo 4
bar 0
bar 1
bar 2
bar 3
bar 4

调用:

run(list(range(5)), [foo, bar], 1)

输出:

foo 0
bar 0
foo 1
bar 1
foo 2
bar 2
foo 3
bar 3
foo 4
bar 4

我们所做的是,如果订单由您的要求决定,我们为(callable, argument_to_callable)创建了对。所以基本上你有一个布尔,“有点”为你复制一个循环。

代码有点难看,我想知道是否有人提出了更好的解决方案。

答案 1 :(得分:0)

嗯,我们总能将空中结果存储在列表中

n = range(10) 
if debug:
    n = list(map(lambda x: foo(x),n))+list(map(lambda x: bar(x),n))
else:
    n = list(map(lambda x: [foo(x),bar(x)],n))

答案 2 :(得分:-1)

预处理器衍生产品会在代码运行之前更改代码。例如,在C语言系列中,编译器在编译之前替换preprocessor块中的所有表达式。

在您的示例中,debug是运行时变量,因此您无法根据该变量更改代码的结构。至少在Python中不是。

然而,总是(好吧,几乎总是)一种可以避免手动操作的方法。 本着真正的预处理器块的精神,在代码运行之前更改代码,我们必须升级并在代码执行之前添加内容。 最简单的方法是将代码作为字符串操作,并在运行时修改字符串。 我不太强调这个人为的例子是unpythonic,但使用exec你可以注入你想要的代码。无论您使用什么功能,解决方案都将始终有效。在这里:

首先,定义调试标志

if_debug = ""
if debug:
    if_debug = "continue\nfor i in range(5):\n    "

最后,将代码包装在exec("")块中。字符串替换在代码发送到解释器进行评估之前发生。

exec("""
for i in range(5):\n
    foo(i)\n    """
+ if_debug + 
   "bar(i)")

有些宏库允许您更改代码的解释方式。例如,请查看MacroPy