@@ -260,6 +260,7 @@ def make_false_iterator():
260260
261261
262262def get_ratio (filter_function , iterable ):
263+ '''Get the ratio of `iterable` items that pass `filter_function`.'''
263264 if isinstance (filter_function , str ):
264265 attribute_name = filter_function
265266 filter_function = lambda item : getattr (item , attribute_name , None )
@@ -272,4 +273,56 @@ def get_ratio(filter_function, iterable):
272273 return n_passed_items / n_total_items
273274
274275
276+ def fill (iterable , fill_value = None , fill_value_maker = None , length = infinity ,
277+ sequence_type = None ):
278+ '''
279+ Iterate on `iterable`, and after it's exhaused, yield fill values.
280+
281+ If `fill_value_maker` is given, it's used to create fill values
282+ dynamically. (Useful if your fill value is `[]` and you don't want to use
283+ many copies of the same list.)
284+
285+ If `length` is given, shortens the iterator to that length.
286+
287+ If `sequence_type` is given, instead of returning an iterator, this
288+ function will return a sequenceo of that type.
289+ '''
290+ iterator = _fill (iterable , fill_value = fill_value ,
291+ fill_value_maker = fill_value_maker ,
292+ length = length )
293+
294+ if sequence_type is None :
295+ return iterator
296+ else :
297+ return sequence_type (iterator )
298+
299+
300+ def _fill (iterable , fill_value = None , fill_value_maker = None , length = infinity ):
301+ if fill_value_maker is not None :
302+ assert fill_value is None
303+ else :
304+ fill_value_maker = lambda : fill_value
305+
306+ iterator = iter (iterable )
307+ iterator_exhausted = False
308+
309+ for i in itertools .count ():
310+ if i >= length :
311+ raise StopIteration
312+
313+ if iterator_exhausted :
314+ yield fill_value_maker ()
315+ else :
316+ try :
317+ yield next (iterator )
318+ except StopIteration :
319+ iterator_exhausted = True
320+ yield fill_value_maker ()
321+
322+
323+
324+
325+
326+
327+
275328
0 commit comments