import itertools itertools.tee(iterable, n=2)
iterable
- итерируемая последовательность,n=2
- int
.n
независимых копий iterable
.Функция tee()
модуля itertools
вернет n
одинаковых, независимых итераторов из одной итерируемой последовательности.
Следующий код Python помогает объяснить, что делает функция itertools.tee()
, хотя фактическая реализация более сложна и использует только одну базовую очередь FIFO
(первым пришёл - первым ушёл).
Функция itertools.tee()
примерно эквивалентна следующему коду:
def tee(iterable, n=2): it = iter(iterable) deques = [collections.deque() for i in range(n)] def gen(mydeque): while True: # когда локальная двухсторонняя очередь пуста if not mydeque: try: # получить новое значение и newval = next(it) except StopIteration: return # добавить его всем очередям for d in deques: d.append(newval) yield mydeque.popleft() return tuple(gen(d) for d in deques)
После того, как itertools.tee()
выполнит разбиение, исходная итерируемая последовательность не должна использоваться где-либо еще. В противном случае итерируемый объект может быть расширен без уведомления объектов.
Итераторы не являются потокобезопасными. При одновременном использовании итераторов, возвращаемых одним и тем же вызовом itertools.tee()
может возникать ошибка RuntimeError
, даже если исходная итерация является поточно-ориентированной.
Функция itertools.tee()
может потребовать значительной памяти, в зависимости от того, сколько временных данных необходимо сохранить. В общем, если один итератор использует большую часть или все данные перед запуском другого итератора, быстрее использовать list()
.
>>> from itertools import tee >>> x = list(range(9,15)) >>> rez = tee(x, 4) >>> for l in rez: ... print(list(l)) ... # [9, 10, 11, 12, 13, 14] # [9, 10, 11, 12, 13, 14] # [9, 10, 11, 12, 13, 14] # [9, 10, 11, 12, 13, 14]