鉴于此代码:
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)
答案 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。