Python:通过其字典属性之一过滤自定义对象列表
Python: filtering a list of custom objects, by one of its dictionary attributes
我正在尝试在我的 class 中创建一个方法,该方法能够通过其字典属性之一过滤此 class 中的对象列表。例如:
在我下面创建的 class Vehicle 中,category 参数将被赋予一个字典键:值组合,如果 Vehicle 则值为 1符合该类别,即:
{'convertible': 1, 'pickup': 0, 'electric': 1}
因此,对于我的 class 车辆,我可以创建一个汽车对象列表:
class Vehicle:
def __init__(self, name, category, price):
self.__name = name
self.__category = category
self.__price = price
lst_cars =
[
Vehicle('Viper', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300,000),
Vehicle('x150', {'convertible': 0, 'pickup': 1, 'electric': 0}, 300,000),
Vehicle('BMW', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300,000)
]
我可以使用 attrgetter 按名称对我的列表进行排序,并使用以下代码将名称作为 属性 传递:
def order_by(lst_cars, property):
lst = []
c = sorted(lst_cars, key=attrgetter(prop))
for car in c:
lst += [car]
return lst
但我真正想要的是一种方法 parse_by(lst_cars, lst_category)
,它接受一个 Vehicle 对象列表和一个类别字符串列表 ['convertible', 'electric']
,它会 return 一个列表这些类别值为 1 的对象的数量。
[
Vehicle('Viper', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300,000),
Vehicle('BMW', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300,000)
]
稍微研究一下我的代码后,我想出了以下似乎可行的方法,因此编辑了一个答案,但下面的其他人也很有帮助:
def parse_by(lst_cars, lst_category):
c = lst_cars
for item in lst_category:
c = list(filter(lambda x: x.category[item] == 1, c))
return c
这是您可能正在寻找的一个简单示例。肯定有更有效的解决方案,但现在这应该对你有帮助。请注意,我删除了属性前面的 __
以便使用我的函数从外部访问它们。否则你将不得不写类似 obj._Vehicle__category
而不是 obj.category
来访问它们。
class Vehicle:
def __init__(self, name, category, price):
self.name = name
self.category = category
self.price = price
lst_cars = [
Vehicle('Viper', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300.000),
Vehicle('x150', {'convertible': 0, 'pickup': 1, 'electric': 0}, 300.000),
Vehicle('BMW', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300.000)
]
def parse_by(lst_cars, lst_category):
output = lst_cars.copy()
for attr in lst_category:
for obj in output:
if not obj.category.get(attr):
output.remove(obj)
return output
for x in parse_by(lst_cars, ['convertible', 'electric']):
print(x.name)
#Viper
#BMW
让我们试试这个,
- 在
Vehicle
class 中定义 parse_by(lst_cars = [], lst_category = [])
,其中 return 布尔值基于搜索过滤器。 __
使变量私有并且在外部不可见,它只能从自己的内部访问 class.
class Vehicle:
def __init__(self, name, category, price):
self.__name = name
self.__category = category
self.__price = price
def parse_by(self, lst_cars, lst_category):
if self.__name in lst_cars and \
all(self.__category.get(c) for c in lst_category):
return True
else:
return False
def __str__(self):
return f"name : {self.__name}, cateogry : {self.__category} price : {self.__price}"
- 使用列表理解来过滤值。
lst_cars = [
Vehicle('Viper', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300000),
Vehicle('x150', {'convertible': 0, 'pickup': 1, 'electric': 0}, 300000),
Vehicle('BMW', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300000)
]
print(
[str(x) for x in lst_cars if x.parse_by(['Viper', 'BMW'], ['convertible'])]
)
def parse_by(lst_cars, lst_category):
validCars = []
for car in lst_cars:
if all([car.getattr(attr) for attr in lst_category]): #any applies logical ANDs on all elements in list
validCars.append(car)
return validCars
[car.getattr(attr) for attr in lst_category]
这会为 lst_cars.
中的特定汽车创建所有类别(属性)的值列表
我正在尝试在我的 class 中创建一个方法,该方法能够通过其字典属性之一过滤此 class 中的对象列表。例如:
在我下面创建的 class Vehicle 中,category 参数将被赋予一个字典键:值组合,如果 Vehicle 则值为 1符合该类别,即:
{'convertible': 1, 'pickup': 0, 'electric': 1}
因此,对于我的 class 车辆,我可以创建一个汽车对象列表:
class Vehicle:
def __init__(self, name, category, price):
self.__name = name
self.__category = category
self.__price = price
lst_cars =
[
Vehicle('Viper', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300,000),
Vehicle('x150', {'convertible': 0, 'pickup': 1, 'electric': 0}, 300,000),
Vehicle('BMW', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300,000)
]
我可以使用 attrgetter 按名称对我的列表进行排序,并使用以下代码将名称作为 属性 传递:
def order_by(lst_cars, property):
lst = []
c = sorted(lst_cars, key=attrgetter(prop))
for car in c:
lst += [car]
return lst
但我真正想要的是一种方法 parse_by(lst_cars, lst_category)
,它接受一个 Vehicle 对象列表和一个类别字符串列表 ['convertible', 'electric']
,它会 return 一个列表这些类别值为 1 的对象的数量。
[
Vehicle('Viper', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300,000),
Vehicle('BMW', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300,000)
]
稍微研究一下我的代码后,我想出了以下似乎可行的方法,因此编辑了一个答案,但下面的其他人也很有帮助:
def parse_by(lst_cars, lst_category):
c = lst_cars
for item in lst_category:
c = list(filter(lambda x: x.category[item] == 1, c))
return c
这是您可能正在寻找的一个简单示例。肯定有更有效的解决方案,但现在这应该对你有帮助。请注意,我删除了属性前面的 __
以便使用我的函数从外部访问它们。否则你将不得不写类似 obj._Vehicle__category
而不是 obj.category
来访问它们。
class Vehicle:
def __init__(self, name, category, price):
self.name = name
self.category = category
self.price = price
lst_cars = [
Vehicle('Viper', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300.000),
Vehicle('x150', {'convertible': 0, 'pickup': 1, 'electric': 0}, 300.000),
Vehicle('BMW', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300.000)
]
def parse_by(lst_cars, lst_category):
output = lst_cars.copy()
for attr in lst_category:
for obj in output:
if not obj.category.get(attr):
output.remove(obj)
return output
for x in parse_by(lst_cars, ['convertible', 'electric']):
print(x.name)
#Viper
#BMW
让我们试试这个,
- 在
Vehicle
class 中定义parse_by(lst_cars = [], lst_category = [])
,其中 return 布尔值基于搜索过滤器。__
使变量私有并且在外部不可见,它只能从自己的内部访问 class.
class Vehicle:
def __init__(self, name, category, price):
self.__name = name
self.__category = category
self.__price = price
def parse_by(self, lst_cars, lst_category):
if self.__name in lst_cars and \
all(self.__category.get(c) for c in lst_category):
return True
else:
return False
def __str__(self):
return f"name : {self.__name}, cateogry : {self.__category} price : {self.__price}"
- 使用列表理解来过滤值。
lst_cars = [
Vehicle('Viper', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300000),
Vehicle('x150', {'convertible': 0, 'pickup': 1, 'electric': 0}, 300000),
Vehicle('BMW', {'convertible': 1, 'pickup': 0, 'electric': 1}, 300000)
]
print(
[str(x) for x in lst_cars if x.parse_by(['Viper', 'BMW'], ['convertible'])]
)
def parse_by(lst_cars, lst_category):
validCars = []
for car in lst_cars:
if all([car.getattr(attr) for attr in lst_category]): #any applies logical ANDs on all elements in list
validCars.append(car)
return validCars
[car.getattr(attr) for attr in lst_category]
这会为 lst_cars.