iterable
APIiter()
to produce an iterator
next()
to get the next
value in sequenceiterable = ['Spring', 'Summer', 'Autumn', 'Winter']
iterator = iter(iterable)
next(iterator) #=> 'Spring'
next(iterator) #=> 'Summer'
next(iterator) #=> 'Autumn'
next(iterator) #=> 'Winter'
next(iterator) #=> NOTE: raises exception of StopIteration
Why is it considered exceptional?
More concrete use a utility function
def first(iterable):
iterator = iter(iterable)
try:
return next(iterator)
except StopIteration:
raise ValueError("iterable is empty")
iter()
next()
StopIteration
iterable: object that implements __iter__()
method
iterator: object that implements the iterable protocol and the __next__()
method
class ExampleIterator:
def __init__(self, data):
self.index = 0
self.data = data
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.data):
raise StopIteration()
result = self.data[self.index]
self.index += 1
return result
class ExampleIterable:
def __init__(self):
self.data = [1, 2, 3]
def __iter__(self):
return ExampleIterator(self.data)
__getitem__()
__getitem__()
must throw IndexErrorclass AlternateIterable:
def __init__(self):
self.data = [1, 2, 3]
def __getitem__(self, idx):
return self.data[idx]
iter()
iter(callable, sentinel)
callable
: object that takes zero argssentinel
: iteration stops when callable
produce this value# sensor.py
import datetime
import itertools
import random
import time
class Sensor:
def __iter__(self):
return self
def __next__(self):
return random.random()
sensor = Sensor()
timestamps = iter(datetime.datetime.now, None)
for stamp, value in itertools.islice(zip(timestamps, sensor), 10):
print(stamp, value)
time.sleep(1)