使用“内置”条件执行for循环的pythonic方法是什么?

时间:2017-10-24 16:07:52

标签: python python-2.7

在类方法中,我有以下内容:

if self.zot == 1:
        for foo in self.bar:
            if self.zot != 1:
                break
            #code that may or may not change self.zot

bar是一个我不想访问和填充的属性,除非绝对必要,所以如果zot不是1,我仍然希望阻止第一次迭代。

Python是python我猜测仍然有一种更简洁的方法来做到这一点。

如下所示?

for foo in self.bar while self.zot == 1:

与python 2.7.x兼容的答案的奖励积分

编辑:在迭代期间是否修改zot部分地与bar的内容无关,因此takewhile是不切实际的。如果bar不是1,则无论如何都不需要访问zot

2 个答案:

答案 0 :(得分:0)

您可以将for转换为while循环并使用iter()next(),虽然它不是非常pythonic并且需要使用try except

iterator = None
while self.zot == 1:
    iterator = iterator or iter(self.bar)
    try:
        current = iterator.next()
        #your code
    except StopIteration:
        break

只有在您第一次进入self.bar时,才会开始使用while

您可以创建代理功能来委派支票。

def check_and_iterate(iterable, predicate):
    i = None
    while predicate():
        i = i or iter(iterable)
        yield i.next()

for foo in check_and_iterate(self.bar, lambda: self.zot == 1):
    #your code

编辑: 正如@ user2357112指出的那样,无论如何都会访问self.bar。您可以使用另一个lambda来推迟它:

def check_and_iterate(getter, predicate):
    i = None
    while predicate():
        i = i or iter(getter())
        yield i.next()

for foo in check_and_iterate(lambda: self.bar, lambda: self.zot == 1):
    #your code

答案 1 :(得分:0)

类似的东西,属性bar处理zot检查

@property
def bar(self):
    itr = iter(self._bar)
    while self.zot == 1:
        yield next(itr)