英文:
Sum together list of F expressions
问题
有没有一种方法可以指定(在注释或汇总中)一系列F
表达式应该在不手动输入F("first_prop") + F("second_prop") + ...
的情况下相加在一起?
我想要类似于Python的sum()
函数的功能,允许您传递可迭代对象并获取可迭代对象中值的总和,即sum([1,2,3])
返回6
。
具体来说,我想要类似于以下的功能:
class Tree(TimeStampedModel):
leaf_count = models.IntegerField()
branch_count = models.IntegerField()
Tree.objects.create(leaf_count=60, branch_count=8)
Tree.objects.create(leaf_count=30, branch_count=3)
# 现在我想要使用我的虚构的IterableSum聚合器注释一个组合计数
combined_sums = list(
Tree.objects.all().annotate(
combined_count=IterableSum(fields=[F("leaf_count"), F("branch_count")])
).values_list("combined_count", flat=True)
)
combined_sums # [68, 33]
我该如何实现这个?
英文:
Is there a way to specify (in an annotation or aggregation) that a sequence of F
expressions should be summed together without manually typing out F("first_prop") + F("second_prop") + ...
?
I want something similar to how python's sum()
function allows you to pass an iterable and get the sum of the values in the iterable i.e. sum([1,2,3])
returns 6
.
Concretely, I want something that looks like this:
class Tree(TimeStampedModel):
leaf_count = models.IntegerField()
branch_count = models.IntegerField()
Tree.objects.create(leaf_count=60, branch_count=8)
Tree.objects.create(leaf_count=30, branch_count=3)
# now I want to annotate a combined count using my imaginary IterableSum aggregator
combined_sums = list(
Tree.objects.all().annotate(
combined_count=IterableSum(fields=[F("leaf_count"), F("branch_count")])
).values_list("combined_count", flat=True)
)
combined_sums # [68, 33]
How can I achieve this?
答案1
得分: 2
唯一的问题在于sum
的初始值是0
。你可以使用functools
库中的reduce
函数:
from functools import reduce
from operator import add
from django.db.models import F
combined_sums = list(
Tree.objects.values(
combined_count=reduce(add, [F('leaf_count'), F('branch_count')]),
flat=True,
)
)
严格来说,这甚至不是必要的,你可以直接使用sum
,因为它会将0
与F('leaf_count')
相加:
from django.db.models import F
combined_sums = list(
Tree.objects.values(
combined_count=sum([F('leaf_count'), F('branch_count')]),
flat=True,
)
)
然后这将在查询中有一个+ 0
,可能不是理想的。这是因为sum
不仅仅可以对整数求和,实际上,你可以对F
对象进行求和:
sum([F('foo'), F('bar')])
英文:
The only problem with sum
is that it starts with 0
as initial value. You can you can use reduce
from functools
:
<pre><code>from functools import reduce
from operator import add
from django.db.models import F
combined_sums = list(
Tree.objects.values(
combined_count=reduce(add, [F('leaf_count'), F('branch_count')]),
flat=True,
)
)</code></pre>
although strictly speaking, that is not even necessary, you can just use sum
, since it will add up 0
with F('leaf_count')
:
<pre><code>from django.db.models import F
combined_sums = list(
Tree.objects.values(
combined_count=sum([F('leaf_count'), F('branch_count')]),
flat=True,
)
)</code></pre>
Then this will have a + 0
in the query, which might not be ideal.
This is because sum
does not sum only integers, indeed, you can for example sum F
objects:
In [11]: sum([F('foo'), F('bar')])
Out[11]: <CombinedExpression: Value(0) + F(foo) + F(bar)>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论