Python:在elif条件下循环

时间:2015-03-31 18:19:24

标签: python if-statement python-3.x

我正在运行Python 3。

是否可以在elif的条件下设置循环?这是我想要实现的基本想法。列表中的项目数不是恒定的。

if some_condition:
    do this
elif [ x.method() for x in list ]:
    do this to x
else:
    do something else

现在,我想到了这一点:

if some_condition:
    do this
for x in list:
    if x.method():
        do this to x
        break

但是我试图避免运行所有if语句,其中有很多内容正在进行中。我希望明确地将其记录在elif部分,而不是else

编辑/更多说明:

似乎我需要的是any( x.method() for x in list ),但也提到x,以便我可以在条件为真时使用x

这是我想要再次获得的整个概念:

if condition:
    do this
elif list[0].method():
    do this to list[0]
elif list[1].method():
    do this to list[1]
...
elif list[n].method():
    do this to list[n]
else:
    do this

其中method()是返回TrueFalse的方法,而n是列表的大小而不是常量。

5 个答案:

答案 0 :(得分:1)

if [ x.method() for x in list ]:
你问,有可能吗?是。但是它做了什么?可能不是你想要的。

对于 list 中的项目数,它将在结果列表中构造一个值。对于列表值,只有零长度的列表将为False。 [False,False,False]为True,因此将执行条件的主体。

如果 x.method()应该影响以下条件决定,您可能正在寻找所有()任何()

if all(x.method() for x in list):   # will require that every *x.method* call return truth.

同样,您可能需要

if any(x.method() for x in list):   # only one required. May not do every .method if it can stop early. Beware side-effects.

答案 1 :(得分:1)

我认为你想要的东西 - 完全在elif中 - 是可能的。您必须评估列表中是否有any这样的值,然后将其绑定到条件中的x 。据我所知,这在Python的语法中是不可能的。 You can not do an assignment in the condition,虽然列表解析中的循环变量可以“泄漏”到外部范围,但对于生成器,为真。

>>> if any(x for x in range(10) if x >= 5):
...     print x
NameError: name 'x' is not defined
>>> if any([x for x in range(10) if x >= 5]):
...     print x
9

在第二种情况(列表)中,我们引用了x,但它是整个列表中的最后一个值,而在第一种情况下(生成器),x不能完全解决了。


相反,这是另一个变体,使用生成器表达式将forif结合起来,并向else添加for以使您的最终else得到充实1}}子句。

if some_condition:
    print "do this"
else:
    for x in (x for x in lst if foo(x)):
        print "do this to", x
        break
    else:
        print "do something else"

答案 2 :(得分:1)

我现在看到了。做出更新编辑所说的Pythonic方法是在找到第一个项目并对其进行操作后进行for循环和中断,然后使用几乎未知且未使用的" else"一个循环。

因为" for / else"习惯用法很少使用,你需要为将来的读者添加一个关于它的评论。

if some_test:
    first_action()
else:
    for item in list:
        if item.method():
            do_this(item)
            break   # process no more of list
    else:   # for-else only entered if no break from the list!
        final_action()

阅读loop elses in the Python Tutorial

答案 3 :(得分:0)

完全不可能做你想做的事,但是你可以用列表推导做类似的事情:

if some_condition:
    do this
else:
    res = [x for x in list if x.method()]
    if res:
        do something to res[0]
    else:
        do something else

为避免对每个值执行x.method(),您还可以使用itertools.dropwhile。以下方法将继续检查x.method(),直到找到一个为真,然后停止并返回x的值。如果找不到任何真实的东西,它会做其他的事情。

from itertools import dropwhile
if some_condition:
    do this
else:
    try:
        res = next(dropwhile(lambda x: not x.method(), x))
        do something to res
    except StopIteration:
        do something else

答案 4 :(得分:0)

只要你不需要在elif块之外引用x,这就可以工作。这感觉最接近你要求的语法,但我仍然可能会使用Kevin或Tobias的答案,因为它们更明确和可读。

 def check_and_do(x):
    b = x.method()
    if b:
        do this to x
    return b

if condition:
    do this
elif any(check_and_do(x) for x in list):
    pass  # Already did this to x in check_and_do
else:
    do something else