简体   繁体   English

如何使此代码用于获取列表中的对象更短?

[英]How can I make this code for getting objects for my list shorter?

I am retrieving database objects to add to a dict, but the keys can't be duplicates, so I've done it this way:我正在检索要添加到字典的数据库对象,但键不能重复,所以我这样做了:

    carb1 = random.choice(carbs)
    protein1 = random.choice(proteins)
    carb2 = Food.objects.filter(category='Carbs').exclude(name=carb1.name)[0]
    protein2 = Food.objects.filter(category='Protein').exclude(name=protein1.name)[0]
    veg1 = random.choice(vegs)
    veg2 = Food.objects.filter(category='Vegetables').exclude(name=veg1.name)[0]

    meals = [carb1, protein1, carb2, protein2]

    exclude_these = [o.name for o in meals]

    carb3 = Food.objects.filter(category='Carbs').exclude(name__in=exclude_these)[0]
    protein3 = Food.objects.filter(category='Protein').exclude(name__in=exclude_these)[0]
    veg3 = Food.objects.filter(category='Vegetables').exclude(name__in=exclude_these)[0]
    meals.append(carb3)
    meals.append(protein3)
    meals.append(veg3)

    exclude_these = [o.name for o in meals]

    carb4 = Food.objects.filter(category='Carbs').exclude(name__in=exclude_these)[0]
    protein4 = Food.objects.filter(category='Protein').exclude(name__in=exclude_these)[0]
    veg4 = Food.objects.filter(category='Vegetables').exclude(name__in=exclude_these)[0]

    meals.append(carb4)
    meals.append(protein4)
    meals.append(veg4)

    exclude_these = [o.name for o in meals]

    carb5 = Food.objects.filter(category='Carbs').exclude(name__in=exclude_these)[0]
    protein5 = Food.objects.filter(category='Protein').exclude(name__in=exclude_these)[0]
    veg5 = Food.objects.filter(category='Vegetables').exclude(name__in=exclude_these)[0]

    meals.append(carb5)
    meals.append(protein5)
    meals.append(veg5)

    exclude_these = [o.name for o in meals]

    carb6 = Food.objects.filter(category='Carbs').exclude(name__in=exclude_these)[0]
    protein6 = Food.objects.filter(category='Protein').exclude(name__in=exclude_these)[0]
    veg6 = Food.objects.filter(category='Vegetables').exclude(name__in=exclude_these)[0]

But this just seems like a ridiculous amount of code to achieve what I want.但这似乎是实现我想要的代码的荒谬数量。

Is there a way I can shorten this?有没有办法可以缩短这个?

It looks like you want to retrieve 6 carbs, 6 proteins, and 6 vegs from your foods table and you don't care which they are (you provide no ordering in the query and take the first of each).看起来你想从你的食物表中检索 6 种碳水化合物、6 种蛋白质和 6 种蔬菜,而你并不关心它们是什么(你在查询中没有提供排序并取每个中的第一个)。 Except the first one is random.除了第一个是随机的。 Maybe you don't care that the first one is picked at random or maybe you want the remaining 5 to be uniformly picked at random as well?也许您不在乎第一个是随机挑选的,或者您可能希望其余 5 个也被统一随机挑选?

Here are some options:以下是一些选项:

carb1, carb2, carb3, carb4, carb5, carb6 = tuple(
    Food.objects.filter(category='Carbs')[:6]
)

And similar for portein and veg.与 portein 和 veg 类似。 Frankly, don't name your variables carbN, just put all of them in a list or tuple.坦率地说,不要将变量命名为 carbN,只需将它们全部放在列表或元组中即可。 carbs = Food....[:6]

If the name column is not unique and you really want 6 carbs that have different names,如果名称列不是唯一的,并且您确实想要 6 个具有不同名称的碳水化合物,

carbs = Food.objects.filter(category='Carbs').distinct('name')[:6]

Distinct on a column instead of the whole record doesn't work in all database backends.不同的列而不是整个记录在所有数据库后端都不起作用。 It works in postgres, but I think it doesn't work in mysql.它适用于 postgres,但我认为它不适用于 mysql。

If you really want 6 random carbs, you can have the database randomize it for you.如果你真的想要 6 种随机碳水化合物,你可以让数据库为你随机化。

carbs = Food.objects.filter(category='Carbs').order_by('?')[:6]

There may be some performance problems with random ordering if your table of foods is large.如果您的食物表很大,随机订购可能会出现一些性能问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM