在python中的javascript' s _.where

时间:2015-11-17 02:10:50

标签: python dictionary

http://underscorejs.org/,有一个下划线实用程序where

_.where(listOfPlays, {author: "Shakespeare", year: 1611}

返回,

[{title: "Cymbeline", author: "Shakespeare", year: 1611},
 {title: "The Tempest", author: "Shakespeare", year: 1611}]

如何在不使用for in迭代的情况下在python中执行此操作?

3 个答案:

答案 0 :(得分:2)

我个人想使用列表推导。但它确实涉及forin

>>> listOfPlays = [{'title': x, 'author': x, 'year': 1611} for x in ('Shakespeare', 'someone')]
>>> listOfPlays
[{'author': 'Shakespeare', 'year': 1611, 'title': 'Shakespeare'}, {'author': 'someone', 'year': 1611, 'title': 'someone'}]
>>> 
>>> [x for x in listOfPlays if x['author'] == 'Shakespeare' and x['year'] == 1611]
[{'author': 'Shakespeare', 'year': 1611, 'title': 'Shakespeare'}]

或者,您可以使用filter

>>> filter(lambda x: x['author'] == 'Shakespeare' and x['year'] == 1611, listOfPlays)
[{'author': 'Shakespeare', 'year': 1611, 'title': 'Shakespeare'}]

已编辑:请注意,上述示例是在Python 2中进行评估的。在Python 3中,内置函数filter返回一个可迭代而不是列表。

答案 1 :(得分:1)

请注意,filter(function, iterable)相当于[item for item in iterable if function(item)]

def filter_by_dict(list_of_dicts, conditions):
    def _check(item):
        # returns True only if first is subset of second
        # in python3 you should use items()
        return conditions.viewitems() <= item.viewitems()

    return filter(_check, list_of_dicts)

TEST = [
    {"title": "Cymbeline", "author": "Shakespeare", "year": 1611},
    {"title": "Otherr", "author": "Shakespeare", "year": 1612},
    {"title": "The Tempest", "author": "Shakespeare", "year": 1611}
]
print(filter_by_dict(TEST, {"author": "Shakespeare", "year": 1611}))

答案 2 :(得分:0)

相当于_.where可以在python中以1行的形式编写为列表解析,但它将使用for ... in语法:

def where(elems, **kwargs):
    """where(iterable, **filter_conditions) --> filtered iterable"""
    return [el for el in elems if all(el.get(k) == v for k, v in kwargs.items())]

或者,使用filter&amp; map以避免使用for ... in

def where(elems, **kwargs):
    """where(iterable, **filter_conditions) --> filter object"""
    def picker(elem): 
        return all(map(lambda x: elem.get(x[0]) == x[1], kwargs.items()))
    return filter(picker, elems)

在python 2上,where函数的两个版本都被称为:

where(listOfPlays, author='Shakespeare', year=1611)

在python 3上,后一个版本需要包含在列表中,因为filter会返回一个过滤器对象,即

list(where(listOfPlays, author='Shakespeare', year=1611))