Extracts the specific element matched by "item in container". Useful for interning or caching applications needing canonical or singleton values.
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)