我想用 Python 和 Django 中的另一个字典列表来过滤字典列表。
我有一个过滤器列表,如下所示:
filters = [{'type': 'make', 'value': 'SEAT'}, {'type': 'model', 'value': 'Acura'}]
Run Code Online (Sandbox Code Playgroud)
我有一个车辆列表如下:
vehicles = [
{'make': 'Audi', 'model': 'A3', 'transmission': 'Manual'},
{'make': 'Audi', 'model': 'A1', 'transmission': 'Automatic'},
{'make': 'Seat', 'model': 'Acura', 'transmission': 'Manual'},
{'make': 'Seat', 'model': 'LEON', 'transmission': 'Manual'},
{'make': 'Skoda', 'model': 'Octavia', 'transmission': 'Manual'},
]
Run Code Online (Sandbox Code Playgroud)
我想获得所有带有make Seat和 的车辆model Acura。因此我想要的结果是:
[
{'make': 'Seat', 'model': 'Acura', 'transmission': 'Manual'}
]
Run Code Online (Sandbox Code Playgroud)
我尝试了如下方法:
def filter_item(vehicle, filters):
for fil in filters:
key = fil['type']
value = fil['value']
if key == 'make':
if vehicle.make == value:
continue
elif key == 'model':
if vehicle.model == value:
continue
else:
return False
return True
vehicles = list(filter(lambda vehicle: filter_item(vehicle, filters), vehicles))
Run Code Online (Sandbox Code Playgroud)
但这给了我所有车辆。
任何想法?
更新
因此,如果我有如下过滤器:
filters = [
{'type': 'make', 'value': 'SEAT'},
{'type': 'model', 'value': 'Acura'},
{'type': 'model', 'value': 'LEON'}
]
Run Code Online (Sandbox Code Playgroud)
我想要下一个结果:
[
{'make': 'Seat', 'model': 'Acura', 'transmission': 'Manual'},
{'make': 'Seat', 'model': 'LEON', 'transmission': 'Manual'},
]
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
我需要更改列表的结构filters吗?
False由于与以下内容vehicle.make不同,您的过滤不会返回value等
您可以将过滤器重写为:
def filter_item(vehicle, filters):
for fil in filters:
key = fil['type']
value = fil['value']
if key == 'make':
if vehicle.make != value:
return False
elif key == 'model':
if vehicle.model != value:
return False
else:
return False
return TrueRun Code Online (Sandbox Code Playgroud)
或者我们可以利用getattr:
def filter_item(vehicle, filters):
for fil in filters:
if fil['value'] != getattr(vehicle, fil['type']):
return False
return TrueRun Code Online (Sandbox Code Playgroud)
def filter_item(vehicle, filters):
return all(fil['value'] == getattr(vehicle, fil['type']) for fil in filters)Run Code Online (Sandbox Code Playgroud)
如果您的目标是过滤 Django 记录,那么我强烈建议在数据库上尽可能多地进行过滤,因为数据库已针对此任务进行了优化。
编辑:您可以对同一字段的析取进行合取。例如通过预处理过滤器:
from collections import defaultdict
filter_dict = defaultdict(set)
for fil in filters:
filter_dict[fil['type']].add(fil['value'])
def filter_item(vehicle):
return all(getattr(vehicle, k) in v for k, v in filter_dict.items())Run Code Online (Sandbox Code Playgroud)
如果你的vehicle不是一个带有属性的对象,而是一个字典,你应该替换getattr(vehicle, k)为vehicle[k].
| 归档时间: |
|
| 查看次数: |
79 次 |
| 最近记录: |