像字典一样搜索命名元组
searching a namedtuple like a dictionary
为了节省内存并避免冗余的数据库存储(是的,可能是预优化),我使用 namedtuple 而不是字典。
但我需要搜索记录集合,我的字典方法是:
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))
不处理 namedtuple
关于如何子类化 namedtuple 以使其像字典一样可搜索的任何提示?
并非每个实例都包含与查询键相同的 key/fields,因此我需要跳过该行而不是抛出 key/attr 错误..
我认为您可以使用 getattr
查看该字段是否存在,如果不存在则引发异常或 return 默认值。
例如,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
试试这个:
return (x for x in D if try_op(op, getattr(x,key,keynotfound),val))
getattr 对属性的作用类似于对字典元素的 get。
最佳解决方案是调用 vars(p)
,假设 p 是您的 namedtuple 实例。这给出了一个 collections.OrderedDict
,你可以像普通字典一样使用它。
为了节省内存并避免冗余的数据库存储(是的,可能是预优化),我使用 namedtuple 而不是字典。
但我需要搜索记录集合,我的字典方法是:
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))
不处理 namedtuple 关于如何子类化 namedtuple 以使其像字典一样可搜索的任何提示? 并非每个实例都包含与查询键相同的 key/fields,因此我需要跳过该行而不是抛出 key/attr 错误..
我认为您可以使用 getattr
查看该字段是否存在,如果不存在则引发异常或 return 默认值。
例如,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
试试这个:
return (x for x in D if try_op(op, getattr(x,key,keynotfound),val))
getattr 对属性的作用类似于对字典元素的 get。
最佳解决方案是调用 vars(p)
,假设 p 是您的 namedtuple 实例。这给出了一个 collections.OrderedDict
,你可以像普通字典一样使用它。