我有一个想要执行到耗尽的循环,或者直到达到某个用户指定的限制。我有一个看起来很糟糕的结构,但我似乎找不到更优雅的表达方式;有一个吗?
def ello_bruce(limit=None):
for i in xrange(10**5):
if predicate(i):
if not limit is None:
limit -= 1
if limit <= 0:
break
def predicate(i):
# lengthy computation
return True
神圣的筑巢!一定有更好的方法。出于工作示例的目的,xrange
用于我通常具有有限但未知长度的迭代器(并且谓词有时返回False)。
答案 0 :(得分:11)
也许这样的事情会好一点:
from itertools import ifilter, islice
def ello_bruce(limit=None):
for i in islice(ifilter(predicate, xrange(10**5)), limit):
# do whatever you want with i here
答案 1 :(得分:2)
我会好好看看itertools库。使用它,我想你会有类似......
# From the itertools examples
def tabulate(function, start=0):
return imap(function, count(start))
def take(n, iterable):
return list(islice(iterable, n))
# Then something like:
def ello_bruce(limit=None):
take(filter(tabulate(predicate)), limit)
答案 2 :(得分:1)
我从
开始if limit is None: return
因为limit
以None
开头时没有任何事情发生(如果在迭代和predicate
的计算中没有理想的副作用 - 如果有的话,那么,在这种情况下你可以做for i in xrange(10**5): predicate(i)
)。
如果limit
不是None
,那么您只想执行max(limit, 1)
的{{1}}计算,这些计算是真的,因此predicate
的{{1}} 1}}会做:
itertools.islice
答案 3 :(得分:1)
您应该删除嵌套的ifs:
if predicate(i) and not limit is None:
...
答案 4 :(得分:0)
你想要做什么似乎非常适合while循环:
def ello_bruce(limit=None):
max = 10**5
# if you consider 0 to be an invalid value for limit you can also do
# if limit:
if limit is None:
limit = max
while max and limit:
if predicate(i):
limit -= 1
max -=1
如果max
或limit
达到零,则循环停止。
答案 5 :(得分:0)
庵。据我了解,predicate
只是计算段,你完全忽略它的返回值,对吗?
这是另一种看法:
import itertools
def ello_bruce(limit=None):
if limit is None:
limiter= itertools.repeat(None)
else:
limiter= xrange(limit)
# since predicate is a Python function
# itertools looping won't be faster, so use plain for.
# remember to replace the xrange(100000) with your own iterator
for dummy in itertools.izip(xrange(100000), limiter):
pass
另外,从return True
的末尾删除不需要的predicate
。