如何使用此可迭代函数否定列表上的搜索?

时间:2014-03-04 16:31:11

标签: python iterator

我编写了一个python函数来搜索iterable:

def iter_search(iterable, **search):
    for item in iterable:
        # Assume we will find something to yield
        yield_me=True

        # Cycle through keys that exist in the search and item
        for key in item.viewkeys() & search:
            if item[key] is not None:
                if item[key] != search[key]:
                    # Key didn't match, don't yield this item
                    yield_me = False
        if yield_me:
            yield item

效果很好,因为我的搜索'key'可以是任意数量的字典键值对:

new_iterable = iter_search(iter, ** { 'C' : 'US', 'Sex' : 'm' })

现在,我试图否定搜索,所以我尝试了:

def iter_search(iterable, **search):
    for item in iterable:
        yield_me=True
        for key in item.viewkeys() & search:
            if item[key] is not None:
                if search[key][0] == '!':
                    if item[key] == search[key][1:]:
                        yield_me = False
                else:
                    if item[key] != search[key]:
                        yield_me = False
        if yield_me:
            yield item

但是现在,当我包含我的否定字符('!')时,它什么都没有产生:

    new_iterable = iter_search(iter, ** { 'C' : '!US', 'Sex' : 'm' })

我错过了一些简单的事情。什么?

编辑 我正在测试我的代码的错误版本!以上工作正常。

2 个答案:

答案 0 :(得分:1)

首先,您的第一个搜索功能可以简化为:

def iter_search(iterable, **search):
    for item in iterable:
        # Cycle through keys that exist in the search and item
        if len(search.viewitems() & item.viewitems()) == len(search):
            yield item

e.g。如果search中的所有(键,值对)与项目项匹配,则匹配,您可以yield

这是一个有效的快速演示:

>>> demo = [
...     {'C': 'US', 'Sex': 'f', 'Age': 31},
...     {'C': 'US', 'Sex': 'm', 'Age': 42},
...     {'C': 'UK', 'Sex': 'm', 'Age': 24},
...     {'C': 'UK', 'Sex': 'f', 'Age': 50},
... ]
>>> list(iter_search(demo, C='US', Sex='m'))
[{'C': 'US', 'Age': 42, 'Sex': 'm'}]

使用否定搜索可以是:

def iter_search(iterable, **search):
    positive = {k: v for k, v in search.iteritems() if v[:1] != '!'}
    negative = {k: v[1:] for k, v in search.viewitems() - positive.viewitems()}
    for item in iterable:
        # Cycle through keys that exist in the search and item
        if len(positive.viewitems() & item.viewitems()) == len(positive):
            if not negative.viewitems() & item.viewitems():
                yield item

因此,积极搜索与完全匹配,并且没有任何否定项匹配。

针对之前定义的相同输入进行演示:

>>> list(iter_search(demo, C='!US', Sex='m'))
[{'C': 'UK', 'Age': 24, 'Sex': 'm'}]

答案 1 :(得分:0)

我不确定我是否理解你,但据我所知,这可能会回答你所寻找的事情 -

def iter_search(iterable, **search):
    for item in iterable:
        yield_me=False
        for key in item.viewkeys() & search:
            if item[key] is not None:
                if search[key][0] == '!':
                    if item[key] == search[key][1:]:
                        yield_me = True
        if yield_me:
            yield item
相关问题