python生成器是列表的良好替代品,在大多数情况下,我希望检查空条件,这是普通生成器无法实现的.我正在尝试编写一个包装器,它将允许检查空状态,但仍然是懒惰的并且提供了生成器的好处.
class mygen:
def __init__(self,iterable):
self.iterable = (x for x in iterable)
self.peeked = False
self.peek = None
def __iter__(self):
if self.peeked:
yield self.peek
self.peeked = False
for val in self.iterable:
if self.peeked:
yield self.peek
self.peeked = False
yield val
if self.peeked:
yield self.peek
self.peeked = False
def __nonzero__(self):
if self.peeked:
return True
try:
self.peek = self.iterable.next()
self.peeked = True
return True
except:
return False
Run Code Online (Sandbox Code Playgroud)
样品用法:
def get_odd(l):
return mygen(x for x in l if x%2)
def print_odd(odd_nums):
if odd_nums:
print "odd numbers found",list(odd_nums)
else:
print "No odd numbers found"
print_odd(get_odd([2,4,6,8]))
print_odd(get_odd([2,4,6,8,7]))
Run Code Online (Sandbox Code Playgroud)
我通常不会实现这种发电机.如何测试迭代器it
是否耗尽有一种惯用的方法:
try:
next_item = next(it)
except StopIteration:
# exhausted, handle this case
Run Code Online (Sandbox Code Playgroud)
用一些项目特定的LBYL习语代替这种EAFP习语似乎令人困惑,根本没有益处.
也就是说,如果我真的想要,我将如何实现这一点:
class MyIterator(object):
def __init__(self, iterable):
self._iterable = iter(iterable)
self._exhausted = False
self._cache_next_item()
def _cache_next_item(self):
try:
self._next_item = next(self._iterable)
except StopIteration:
self._exhausted = True
def __iter__(self):
return self
def next(self):
if self._exhausted:
raise StopIteration
next_item = self._next_item
self._cache_next_item()
return next_item
def __nonzero__(self):
return not self._exhausted
Run Code Online (Sandbox Code Playgroud)