像字典一样搜索命名元组

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,你可以像普通字典一样使用它。