Python:While循环,根据不同条件执行相同的代码。优雅与开销

3
在Python中: 我想在while循环中执行相同的代码块,但在不同的条件下执行,并使用标志来指定应检查哪个条件。 此外,在此段程序中,这些标志将不会更改,并且只有一个标志将在此程序段中处于活动状态。
我可以按照以下方式实现:
#user inputs flag
if flag == "flag1": flag1 = True
elif flag == "flag2": flag2 = True
#...
#define parameters    
while (flag1 and condition1) or (flag2 and condition2) ... or (flagN and conditionN):
    #do stuff #using parameters

这种方法是可以的,因为它只会检查标志,而不是每次计算每个括号的条件,这是由于在Python中“and”的工作方式导致的。

或者

def dostuff(parameters):
    #do stuff

#user inputs flag
if flag == "flag1": flag1 = True
elif flag == "flag2": flag2 = True
#...

#define parameters

if flag1:
    while(condition1):
        dostuff(parameters)
elif flag2:
    while(condition2):
        dostuff(parameters)
etc... down to N

也许使用相同的开销可以实现同样的效果。

我只是想知道是否有人可以建议更好的方法,从编程实践和可读性方面考虑,或者这是最好的一般方法。

谢谢。


1
你的例子并不相等: 如果第一个例子中标志的状态发生变化,如果新的标志条件匹配,循环可能会继续。但是,在像你第二个例子中首先检查标志时,这是不可能的。 - Finwood
1
谢谢Finwood,说得好。这些标志在执行过程中不会改变。 - MrJanx
1
@MrJanx,您的已接受答案和您自己的代码并没有做同样的事情。您可以这样做for cond in list_of_conditions:while cond...,根本没有检查标志,如果标志具有重复值,则会丢失条件,因为您将具有重复键。 - Padraic Cunningham
1
是的。我对lambda字典感到满意。标志只是一个标记,用于检查哪个条件必须被检查,而在这种设置中,只需要检查一个条件,所以没问题。如果需要同时检查多个条件,我的代码也可以工作,这就是为什么一开始我并不完全满意它 - 它似乎是不必要的。 - MrJanx
@MrJanx,您仍然不能有重复的键,每个标志的潜在值是什么? - Padraic Cunningham
显示剩余6条评论
2个回答

4
您可以使用任何一种:
while any((flag1 and condition1),(flag2 and condition2),(flagN and conditionN))

你的两种方法之间也有差别,如果任何条件可以影响另一个条件,则这两个示例可能会表现不同。

你还可以创建一组配对并进行迭代:

data = ((flag1, condition1),(flag2, condition2),(flagN,conditionN))

for flag, cond in data:
   if flag:
       while cond:
         do_stuff(parameters)

它将避免重复代码,使代码易读。

谢谢。我已经更新了帖子,以明确标志在执行期间不会更改,并且一次只能激活一个标志。 - MrJanx
你可以用 while flag and cond: 替换 if flag: while cond: - Maxime Chéramy
@Maxime,那不是同一件事。 - Padraic Cunningham
为什么?OP表示:“在这种情况下,标志在执行过程中不会改变”。 - Maxime Chéramy
@Maxime,确切地说,为什么要反复检查不会改变的东西呢?反正这也无关紧要,因为OP已经更改了问题要求。 - Padraic Cunningham
并没有完全改变需求,只是澄清了一下。感谢你们两位。如果我需要检查多个条件,Padraic的解决方案更好,因为我将来可能需要这样做。而只需要检查一个条件时,Maxines的解决方案很棒。 - MrJanx

4
您可以使用一个 lambda 表达式的字典:

。该技巧与 IT 相关。

conditions = {
    flag1: lambda: cond1,
    flag2: lambda: cond2,
    flag3: lambda: cond3}

while conditions[flag]():
    do_stuff(parameters)

例子:

conditions = {
    "flag1": lambda: x < 10,
    "flag2": lambda: x < 3,
    "flag3": lambda: x < 5}

x = 0
while conditions["flag2"]():
    print(x)
    x += 1

输出:

0
1
2

谢谢。我喜欢这个! - MrJanx
标记(flag)来自哪里? - Padraic Cunningham
1
这是一个变量或常量或其他什么东西。这就是我理解的“带有标志以检查哪个条件”的方式。 - Maxime Chéramy
这只检查条件是否为真,而不检查标志是否也为True。 - Padraic Cunningham
1
当然,但是在之前你可以指定:flag = “flag1”然后稍后:while conditions[flag]: #做一些事情如果我没有在问题中解释清楚,任何时候只会有一个标志是真的。 - MrJanx

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