如何使用python iterable执行灵活的搜索生成器?

时间:2013-11-25 19:51:12

标签: python dictionary iterator

编辑:原来这不是一个问题。我设法让这个工作,因为我或多或少输入了这个。

我有一个在线csv表数据库,我用cgi脚本查询。该脚本可以使用几个可选的过滤器参数,但添加新的过滤器意味着我必须将if语句加倍。

例如:

records = list()
with open (csv_datafile, 'r') as data: 
    data_reader = csv.DictReader(data, fieldnames=DATA_FIELDS)
    if product is None:
        records.extend(record for record in data_reader if id_start < record['id'] <= id_end)
    else:
        records.extend(record for record in data_reader if id_start < record['id'] <= id_end and record['code'] == product)

你可以看到,如果我添加另一个搜索条件,这个模式就会崩溃,因为我必须在上面的if个句子中嵌套冗余if。

我有没有办法使用迭代器来做到这一点?我的想法是:

def data_search(iterator, **search)
    for item in iterable:
        yield_me=True
        for key in item.viewkeys() & search:
            if item[key] is not None:
                if item[key] != search[key]:
                    yeild_me=False
        if yield_me:
            yield item

然后要集成的代码就像:

search = dict()
if product_search:
    search['code'] = product

if vendor_search:
    search['vendor'] = vendor

records = list()
with open (csv_datafile, 'r') as data: 
    data_reader = csv.DictReader(data, fieldnames=DATA_FIELDS)
    data_reader = data_search(data_reader, **search)
    records.extend(record for record in data_reader if id_start < record['id'] <= id_end)

我应该继续这种方法,还是有更好的方法?

1 个答案:

答案 0 :(得分:0)

我认为你不需要发电机。我认为你在构建搜索条件方面走在正确的轨道上(尽管如果你可以将它们作为名称/值对传入一个更容易使用的字典中),但是执行它可以更简单。

with open(csv_datafile, 'r') as data:
    data_reader = csv.DictReader(data, fieldnames=DATA_FIELDS)
    records = [record for record in data_reader if all(record.get(filter_key) == filter_value for (filter_key, filter_value) in search.iteritems()) and id_start < record['id'] <= id_end]

如果您愿意,可以使用filter使用不同的表达式,并且我可能会使passes_search_filters辅助函数具有易读性。