Нет общего пути. Ваш даже не работает:
>>> def is_iterable_longer_than(iterable, n):
... return n <= len(itertools.islice(iterable, n))
...
>>> is_iterable_longer_than([], 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in is_iterable_longer_than
TypeError: object of type 'itertools.islice' has no len()
Единственный способ сказать, если итератор имеет, по крайней мере, n
объекты в нем перебрать его, пока вы не получите n
объекты или выбежать. К сожалению, некоторые итерации могут повторяться только один раз. Если вы не заботитесь об использовании содержимого Iterable, вы можете сделать это:
def is_iterable_longer_than(iterable, n):
return n == sum(1 for _ in itertools.islice(iterable, n))
Если вам необходимо использовать содержимое из итерации, вы можете создать еще один Iterable, который выглядит как оригинал:
def is_iterable_longer_than(iterable, n):
iter1, iter2 = itertools.tee(iterable)
return sum(1 for _ in itertools.islice(iter1, n)) == n, iter2
в то время как мы на это, мы могли бы также попробовать len
, только в случае, если это работает:
def is_iterable_longer_than(iterable, n):
iter1, iter2 = itertools.tee(iterable)
try:
return len(iterable) >= n, iter2
except TypeError:
return sum(1 for _ in itertools.islice(iter1, n)) == n, iter2
Невозможно сделать это, не оценивая по крайней мере значения 'n' от генератора. –
@JoelCornett, я знал, что мне нужно будет оценить генератор. Я хотел узнать лучший способ. Очевидно, что я не хочу оценивать больше, чем необходимо, и было бы здорово не иметь промежуточных структур данных. И я бы хотел, чтобы он был очень ясным и довольно кратким. –