根据属性表达式对对象进行排序

时间:2019-06-04 05:27:17

标签: python sorting object

给出一个对象列表,我试图根据给定的属性对对象进行降序排序,并根据该属性对表达式进行排序。 我的函数传递了一个参数,该参数将是我将用于比较的属性。我要计算所选营养素属性与卡路里属性的比率,例如(x。营养素/ x。卡路里)。现在有一些极端的情况我不得不感到厌倦。第一个x.calorie可以为零。第二个x。营养素可能<1.0,因为我想按降序给出x.calorie的x。营养素比例,这将提供错误的结果。如果您知道一种比使用if语句从function参数中选择属性更好的方法,则可以加分。例如,营养物可能是[脂肪,碳水化合物,蛋白质],如果我的功能通过了,营养物=脂肪,则x。营养!= x。脂肪。食品类数据成员,名称,蛋白质,碳水化合物,脂肪,卡路里,派系,蛋白质卡路里,碳水化合物卡路里,脂肪卡路里。我想根据给定营养素(“蛋白质”,“碳水化合物”或“脂肪”)的卡路里百分数对食物清单进行排序,该清单需要就位。

我尝试使用attrgetter,这不允许我划分属性。我尝试了一个lambda函数,可在其中缩放值并进行归一化,但仍未按照正确的顺序对列表进行排序。

def sort_food_list(foods, nutrient): 
    if nutrient == 'protein':
        foods.sort(key=lambda x: (x.protein * 100) / x.calories if (x.calories * 100) != 0 else 0, reverse=True)

    if nutrient == 'carbs':
        foods.sort(key=lambda x: (x.carbs * 100) / (x.calories * 100) if x.calories != 0 else 0, reverse=True)

    if nutrient == 'fat':
        foods.sort(key=lambda x: (x.fat * 100) / (x.calories * 100) if x.calories != 0 else 0, reverse=True)

1 个答案:

答案 0 :(得分:0)

尝试下面的代码。它涵盖了您提出的大多数观点。

class Food:
    def __init__(self, name, protein, carbs, fat, calories=0):
        self.name = name
        self.protein = protein
        self.carbs = carbs
        self.fat = fat
        self.calories = calories

    def __repr__(self):
        return '[name: {} protein: {} carbs: {} fat: {} calories: {}]'.format(self.name, self.protein, self.carbs,
                                                                              self.fat, self.calories)


foods = [Food('F1', 12, 34, 56, 1), Food('F2', 11, 4, 16, 11), Food('F3', 11, 5, 56, 11), Food('F4', 1, 277, 3, 4),
         Food('F5', 1234, 77, 333)]


def sort_foods(foods, nutrient):
    foods.sort(key=lambda x: ((getattr(x, nutrient) * 100) / x.calories) if x.calories else 0, reverse=True)


sort_foods(foods, 'fat')
print('By fat')
print(foods)
print()

print('By protein')
sort_foods(foods, 'protein')
print(foods)
print()

print('By carbs')
sort_foods(foods, 'carbs')
print(foods)