Существует ли единый способ узнать, будет ли итерируемый объект итерацией?
Предположим, что у вас есть определенная функция crunch
, которая запрашивает итерируемый объект для параметра и использует его много раз. Что-то вроде:
def crunch (vals):
for v in vals:
chomp(v)
for v in vals:
yum(v)
(примечание: объединение двух циклов for
не является опцией).
Возникает проблема, если функция вызывается с помощью итерации, которая не является списком. В следующем вызове функция yum
никогда не выполняется:
crunch(iter(range(4))
Мы могли бы в принципе исправить это, переопределив функцию crunch
следующим образом:
def crunch (vals):
vals = list(vals)
for v in vals:
chomp(v)
for v in vals:
yum(v)
Но это приведет к использованию дважды памяти, если вызов crunch
:
hugeList = list(longDataStream)
crunch(hugeList)
Мы могли бы исправить это, указав crunch
следующим образом:
def crunch (vals):
if type(vals) is not list:
vals = list(vals)
for v in vals:
chomp(v)
for v in vals:
yum(v)
Но все же там будет colud в случае, когда вызывающий код хранит данные в чем-то, что
- нельзя использовать
- не список
Например:
from collections import deque
hugeDeque = deque(longDataStream)
crunch(hugeDeque)
Было бы неплохо иметь предикат isconsumable
, так что мы можем определить crunch
следующим образом:
def crunch (vals):
if isconsumable(vals):
vals = list(vals)
for v in vals:
chomp(v)
for v in vals:
yum(v)
Есть ли решение этой проблемы?