如何知道生成的序列最多是一定长度 [英] How to know a generated sequence is at most a certain length
问题描述
我想知道生成的序列是否少于2个条目.
I want to know whether a generated sequence has fewer than 2 entries.
>>> def sequence():
... for i in xrange(secret):
... yield i
我效率低下的方法是创建一个列表,并测量其长度:
My inefficient method is to create a list, and measure its length:
>>> secret = 5
>>> len(list(sequence())) < 2
True
很显然,这消耗了整个生成器.
Obviously, this consumes the whole generator.
在我的真实情况下,生成器可能正在穿越大型网络.我想进行检查而不消耗整个生成器,也不构建一个大型列表.
In my real case the generator could be traversing a large network. I want to do the check without consuming the whole generator, or building a large list.
在itertools文档中有一个食谱:
There's a recipe in the itertools documentation:
def take(n, iterable):
"Return first n items of the iterable as a list"
return list(islice(iterable, n))
这只会建立一个最大长度为n
的列表,这更好.
This only builds a list of max length n
, which is better.
所以我可以说:
>>> len(take(2, sequence()) < 2
是否还有一种更Python化,更有效的方式来做到这一点?
Is there an even more pythonic, efficient way to do it?
推荐答案
使用take
的解决方案使用islice
,构建一个列表并获取其长度:
The solution using take
uses islice
, builds a list and takes the length of it:
>>> from itertools import islice
>>> len(list(islice(sequence(), 2))
2
为避免创建列表,我们可以使用sum
:
To avoid creating the list we can use sum
:
>>> sum(1 for _ in islice(sequence(), 2)
2
这大约需要70%的时间:
This takes about 70% of the time:
>>> timeit('len(list(islice(xrange(1000), 2)))', 'from itertools import islice')
1.089650974650752
>>> timeit('sum(1 for _ in islice(xrange(1000), 2))', 'from itertools import islice')
0.7579448552500647
包装:
>>> def at_most(n, elements):
... return sum(1 for _ in islice(elements, n + 1)) <= n
>>> at_most(5, xrange(5))
True
>>> at_most(2, xrange(5))
False
这篇关于如何知道生成的序列最多是一定长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!