Welcome, guest | Sign In | My Account | Store | Cart

Extracts the specific element matched by "item in container". Useful for interning or caching applications needing canonical or singleton values.

Python, 32 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class _CaptureEq:
    'Object wrapper that remembers "other" for successful equality tests.'
    def __init__(self, obj):
        self.obj = obj
        self.match = obj
    def __eq__(self, other):
        result = (self.obj == other)
        if result:
            self.match = other
        return result
    def __getattr__(self, name):  # support hash() or anything else needed by __contains__
        return getattr(self.obj, name)

def get_equivalent(container, item, default=None):
    '''Gets the specific container element matched by: "item in container".

    Useful for retreiving a canonical value equivalent to "item".  For example, a
    caching or interning application may require fetching a single representative
    instance from many possible equivalent instances).

    >>> get_equivalent(set([1, 2, 3]), 2.0)             # 2.0 is equivalent to 2
    2
    >>> get_equivalent([1, 2, 3], 4, default=0)
    0
    '''
    t = _CaptureEq(item)
    if t in container:
        return t.match
    return default

import doctest
print doctest.testmod()

For applications that care about object identity, this recipes provides a fast way to extract specific dictionary keys and set elements equivalent to a given item.

Successful set and dictionary lookups using singleton values run quicker than lookups requiring a full equality test (internally, equality testing is bypassed for identical elements).

The recipe's running time is proportional to the performance of the "in" operator, O(1) for dictionaries and sets and O(n) for tuples and lists (with an early-out upon encountering the first match).

For applications needing an exception when the item is not found, change the last line of get_equivalent() to: raise KeyError(item)