习惯于尝试循环遍历空迭代的惯用方法

aar*_*ing 5 python iterable coding-style

假设我循环遍历一个iterable,并希望在迭代器为空时采取一些操作.我能想到的两个最好的方法是:

for i in iterable:
     # do_something
if not iterable:
    # do_something_else
Run Code Online (Sandbox Code Playgroud)

empty = True
for i in iterable:
    empty = False
    # do_something
if empty:
    # do_something_else
Run Code Online (Sandbox Code Playgroud)

第一个取决于可迭代是一个集合(当迭代被传递到循环所在的函数/方法时是无用的)而第二个集合empty在每次遍历循环时似乎很难看.

还有另一种我缺失的方式或者是最好的第二种方式吗?如果有一些我可以添加到循环语句中的子句会为我处理这个,就像elsemake not_found标志消失那样真的很酷.


我不是在寻找聪明的黑客.

我不是在寻找涉及大量代码的解决方案

我正在寻找一个简单的语言功能.我正在寻找一种清晰pythonic的方法来迭代一个iterable并采取一些动作,如果iterable是空的,任何有经验的python程序员都会理解.如果我能在没有在每次迭代时设置标志的情况下这样做,那就太棒了.如果没有这样做的简单成语,那就算了吧.

Joc*_*zel 3

我认为这是最干净的方法:

# first try with exceptions
def nonempty( iter ):
    """ returns `iter` if iter is not empty, else raises TypeError """
    try:
        first = next(iter)
    except StopIteration:
        raise TypeError("Emtpy Iterator")
    yield first
    for item in iter:
        yield item


# a version without exceptions. Seems nicer:
def isempty( iter ):
    """ returns `(True, ())` if `iter` if is empty else `(False, iter)`
         Don't use the original iterator! """
    try:
        first = next(iter)
    except StopIteration:
        return True, ()
    else:
        def iterator():
            yield first
            for item in iter:
                yield item
        return False, iterator()



for x in ([],[1]):
    # first version
    try:
        list(nonempty(iter(x))) # trying to consume a empty iterator raises
    except TypeError:
        print x, "is empty"
    else:
        print x, "is not empty"

    # with isempty
    empty, it = isempty(iter(x))
    print x,  "is", ("empty" if empty else "not empty")
Run Code Online (Sandbox Code Playgroud)