@@ -754,10 +754,15 @@ def value_transform(x): return f(x[1])
754754 return ret
755755
756756
757- def partition (src , key = bool ):
757+ def partition (src , key = bool , * keys ):
758758 """No relation to :meth:`str.partition`, ``partition`` is like
759- :func:`bucketize`, but for added convenience returns a tuple of
760- ``(truthy_values, falsy_values)``.
759+ :func:`bucketize`, but for added convenience returns a collection for
760+ each predicate passed.
761+
762+ ``partition`` now accepts multiple *key* functions and will return
763+ ``N + 1`` lists for ``N`` predicates. Each value from *src* is placed
764+ into the first list whose predicate evaluates to ``True`` with values
765+ that match none of the predicates placed in the last list.
761766
762767 >>> nonempty, empty = partition(['', '', 'hi', '', 'bye'])
763768 >>> nonempty
@@ -772,9 +777,37 @@ def partition(src, key=bool):
772777 >>> decimal_digits, hexletters = partition(string.hexdigits, is_digit)
773778 >>> ''.join(decimal_digits), ''.join(hexletters)
774779 ('0123456789', 'abcdefABCDEF')
780+
781+ Multiple predicates may be supplied to divide into more buckets:
782+
783+ >>> positive, negative, zero = partition(range(-1, 2),
784+ ... lambda i: i > 0,
785+ ... lambda i: i < 0)
786+ >>> positive, negative, zero
787+ ([1], [-1], [0])
775788 """
776- bucketized = bucketize (src , key )
777- return bucketized .get (True , []), bucketized .get (False , [])
789+ if not is_iterable (src ):
790+ raise TypeError ('expected an iterable' )
791+
792+ def _make_key_func (k ):
793+ if isinstance (k , str ):
794+ return lambda x , k = k : getattr (x , k , False )
795+ if callable (k ):
796+ return k
797+ raise TypeError ('expected key to be callable or a string' )
798+
799+ key_funcs = [_make_key_func (key )] + [_make_key_func (k ) for k in keys ]
800+ parts = [[] for _ in range (len (key_funcs ) + 1 )]
801+
802+ for val in src :
803+ for idx , func in enumerate (key_funcs ):
804+ if func (val ):
805+ parts [idx ].append (val )
806+ break
807+ else :
808+ parts [- 1 ].append (val )
809+
810+ return tuple (parts )
778811
779812
780813def unique (src , key = None ):
0 commit comments