2015-02-28 9 views
5

для сохранения памяти & избежать избыточного хранилища БД (да, возможно, для предварительной оптимизации), я использую 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, чтобы сделать его доступным для поиска как Dict? И не каждый экземпляр будет содержать тот же ключ/поля, что и ключ запроса, поэтому мне нужно пропустить эту строку, а не бросать ошибку ключа/attr.

+0

Я бы хотел, чтобы эта функция запроса работала для обоих типов данных, поэтому вместо того, чтобы изменять get getr, я буду подклассифицировать namedtuple и добавить метод get, вызывающий getattr, чтобы интерфейс оставался прежним. ..... любые проблемы с этим? – Dewey

ответ

7

Я думаю, вы можете использовать getattr, чтобы узнать, существует ли поле и либо повышать исключение, либо возвращать значение по умолчанию, если это не так.

Например, 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 
0

Попробуйте это:

return (x for x in D if try_op(op, getattr(x,key,keynotfound),val)) 

GetAttr работает аналогично для атрибутов, как получить для словарных элементов.

1

Лучшим решением является вызов vars(p), предполагая, что p - ваш экземпляр namedtuple. Это дает collections.OrderedDict, который вы можете использовать, как обычный словарь.

 Смежные вопросы

  • Нет связанных вопросов^_^