简体   繁体   English

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

[英]What is the pythonic way of doing a for loop with these conditions “built in”?

In a class method I have the following: 在类方法中,我有以下内容:

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

bar is a property that I'd rather not access and populate unless absolutely necessary, so if zot isn't 1 I'd still like to prevent that first iteration. bar是一个我绝对不希望访问和填充的属性,除非绝对必要,所以如果zot不是1,我仍然希望阻止第一次迭代。

Python being python I'm guessing there's still a way cleaner way to do this. Python是python我想还是有一种更干净的方法可以做到这一点。

Something like the following? 类似于以下内容?

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

Bonus points for an answer compatible with python 2.7.x 与python 2.7.x兼容的答案的加分点

EDIT: Whether zot is modified during the iteration is partially independent of bar 's contents so takewhile is impractical. 编辑:无论zot的迭代期间被修改是部分独立的bar的内容,以便takewhile是不切实际的。 Either way bar needs to not be accessed in the first place if zot isn't 1. 如果zot不是1,则不需要首先访问任一方式的bar

You can convert the for into a while loop and use iter() and next() , although it is not very pythonic and would require using a try except . 你可以转换forwhile环和使用iter()next() ,虽然不是很符合Python和需要使用try except

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

This will start using self.bar only when you go into the while for the first time. 仅当您第一次进入while时,它将开始使用self.bar

You may create a proxy function to delegate the check. 您可以创建一个代理功能来委托检查。

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

EDIT: As @user2357112 pointed out, self.bar is accessed anyway. 编辑:正如@ user2357112所指出的,无论如何self.bar访问self.bar You can defer it by using another lambda: 您可以使用另一个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

something like this, with property bar handling the zot checking 这样的事情,用属性bar处理zot检查

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM