to conserve memory & avoid redundant DB storage (yes possibly pre-optimizing), I'm using namedtuple instead of dictionary.
But I need to search the collection of recs and my dictionary approach is:
import operator
def query(D,key,val, keynotfound=None):
'''
D: a list of dictionaries (but I want it to be namedtuples)
key: the key to query
val: the value to search for
keynotfound: value if key is not found
Returns elements in D such that operator(D.get(key,None), val) is true
'''
op = operator.eq
def try_op(f,x,y):
try:
return f(x,y)
except Exception, exc:
return False
return (x for x in D if try_op(op, x.get(key,keynotfound),val))
not working on namedtuple Any tips on how to subclass namedtuple to make it searchable like a dict? And not every instance will contain the same key/fields as the query-key so I need to skip that row rather than throw a key/attr error..
I think you can use getattr
to see if the field exists and either raise an exception or return a default value if it doesn't.
For example, based on the namedtuple documentation:
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
# An instance of the namedtuple
p = Point(1, 2)
In [1]: getattr(p, "x")
Out[1]: 1
In [2]: getattr(p, "z")
...
AttributeError: 'Point' object has no attribute 'z'
In [3]: getattr(f, "z", None)
Out[3]: None
Try this:
return (x for x in D if try_op(op, getattr(x,key,keynotfound),val))
getattr works similar for attributes as get for dictionary elements.
The best solution is to call vars(p)
, assuming p is your namedtuple instance. This gives a collections.OrderedDict
that you can use like a normal dictionary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With