@@ -132,29 +132,6 @@ def get_length(iterable):
132132 return i
133133
134134
135- def product (* args , ** kwargs ):
136- '''
137- Cartesian product of input iterables.
138-
139- Equivalent to nested for-loops in a generator expression. `product(A, B)`
140- returns the same as `((x,y) for x in A for y in B)`.
141-
142- More examples:
143-
144- list(product('ABC', 'xy')) == ['Ax', 'Ay', 'Bx', 'By', 'Cx', 'Cy']
145-
146- list(product(range(2), repeat=2) == ['00', '01', '10', '11']
147-
148- '''
149- # todo: revamp, probably take from stdlib
150- pools = list (map (tuple , args )) * kwargs .get ('repeat' , 1 )
151- result = [[]]
152- for pool in pools :
153- result = [x + [y ] for x in result for y in pool ]
154- for prod in result :
155- yield tuple (prod )
156-
157-
158135def iter_with (iterable , context_manager ):
159136 '''Iterate on `iterable`, `with`ing the context manager on every `next`.'''
160137
@@ -173,30 +150,6 @@ def iter_with(iterable, context_manager):
173150 yield next_item
174151
175152
176- def izip_longest (* iterables , ** kwargs ):
177- '''
178- izip_longest(iter1 [,iter2 [...]], [fillvalue=None]) -> izip_longest object
179-
180- Return an `izip_longest` object whose `.__next__()` method returns a
181- `tuple` where the i-th element comes from the i-th iterable argument. The
182- `.__next__()` method continues until the longest iterable in the argument
183- sequence is exhausted and then it raises `StopIteration`. When the shorter
184- iterables are exhausted, `fillvalue` is substituted in their place. The
185- `fillvalue` defaults to `None` or can be specified by a keyword argument.
186- '''
187- # This is a really obfuscated algorithm, simplify and/or explain
188- fill_value = kwargs .get ('fillvalue' , None )
189- def sentinel (counter = ([fill_value ] * (len (iterables ) - 1 )).pop ):
190- yield counter ()
191- fillers = itertools .repeat (fill_value )
192- iterables = [itertools .chain (iterable , sentinel (), fillers ) for iterable
193- in iterables ]
194- try :
195- yield from zip (* iterables )
196- except IndexError :
197- raise StopIteration
198-
199-
200153def get_items (iterable , n , container_type = tuple ):
201154 '''
202155 Get the next `n` items from the iterable as a `tuple`.
@@ -223,32 +176,27 @@ def double_filter(filter_function, iterable):
223176 true_deque = collections .deque ()
224177 false_deque = collections .deque ()
225178
226- def process_value ():
227- value = next (iterator )
228- if filter_function (value ):
229- true_deque .append (value )
230- else :
231- false_deque .append (value )
232-
233179 def make_true_iterator ():
234180 while True :
235181 try :
236182 yield true_deque .popleft ()
237183 except IndexError :
238- try :
239- process_value ()
240- except StopIteration :
241- break
184+ value = next (iterator ) # `StopIteration` exception recycled.
185+ if filter_function (value ):
186+ yield value
187+ else :
188+ false_deque .append (value )
242189
243190 def make_false_iterator ():
244191 while True :
245192 try :
246193 yield false_deque .popleft ()
247194 except IndexError :
248- try :
249- process_value ()
250- except StopIteration :
251- break
195+ value = next (iterator ) # `StopIteration` exception recycled.
196+ if filter_function (value ):
197+ true_deque .append (value )
198+ else :
199+ yield value
252200
253201 return (make_true_iterator (), make_false_iterator ())
254202
0 commit comments