[Python-Dev] itertools additions: one(), single_valued()

Andreas Klöckner lists at informa.tiker.net
Mon May 26 17:29:49 CEST 2008


Hi all,

I find the following two operations functions useful and general enough that I 
would like to propose them for addition to itertools:

8< -------------------------------------------------------------------------
def single_valued(iterable):
    it = iter(iterable)
    try:
        first_item = it.next()
    except StopIteration:
        raise ValueError, "empty iterable passed to 'single_valued()'"

    for other_item in it:
        if other_item != first_item:
            raise ValueError, "non-single-valued iterable'"
        
    return first_item
8< -------------------------------------------------------------------------

This first one embodies the assertion that all values of the iterable are 
identical. If they are, that value is returned. Otherwise, an exception is 
thrown. Maybe this should be rephrased such that the assertion part is 
evaluated via an actual "assert", thereby turning it off in optimized mode.

Example use case: You get a list of lists, and expect each to be the same 
length. Typical treatment:

  list_len = len(lists[0])

New treatment:

  list_len = single_valued(len(l) for l in lists)

Added benefits: The assumption is verified and clearly visible from the 
source. "lists" may now be an iterable. 

8< -------------------------------------------------------------------------
def one(iterable):
    it = iter(iterable)
    try:
        v = it.next()
    except StopIteration:
        raise ValueError, "empty iterable passed to 'one()'"

    try:
        v2 = it.next()
        raise ValueError, "iterable with more than one entry passed 
to 'one()'"
    except StopIteration:
        return v
8< -------------------------------------------------------------------------

This one is a blatant rip-off from SQLAlchemy. It basically allows most 
searches to be written using generator expressions:

  what_i_am_looking_for = one(item for item in items if predicate(item))

This also encodes and checks the assumption that the sought item is unique 
within the list of candidates. Again, the assertion part could be turned off 
in optimized mode.

Opinions?

Andreas

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
URL: <http://mail.python.org/pipermail/python-dev/attachments/20080526/04aa663b/attachment-0001.pgp>


More information about the Python-Dev mailing list