Python将None转换为十进制数

3
如何将Python中的None对象转换为Decimal对象。
代码:
c['suspended_amount'] = sum([owned_license.charge_amount for owned_license in log.owned_licenses.all()])

错误:

TypeError: unsupported operand type(s) for +: 'decimal.Decimal' and 'NoneType'
2个回答

4

只需跳过这些值:

c['suspended_amount'] = sum(owned_license.charge_amount
                            for owned_license in log.owned_licenses.all() 
                            if owned_license.charge_amount)

我去掉了方括号[..]; sum()函数需要一个可迭代对象,我使用生成器表达式提供了它所需的。使用方括号会创建一个列表推导式,这会不必要地构建所有值的完整列表。Sum只需要一个接一个地获取值,它们不需要一开始就全部存在。

更好的做法是请数据库仅包含那些charge_amount不为NULL的行:

c['suspended_amount'] = sum(
    owned_license.charge_amount
    for owned_license in log.owned_licenses.exclude(charge_amount__isnull=True).all())

更好的方式是让数据库为您进行计算:

from django.db.models import Sum

c['suspended_amount'] = (
    log.owned_licenses.exclude(charge_amount__isnull=True)
        .aggregate(Sum('charge_amount'))['charge_amount__sum'])

请查看聚合文档

请注意,Martijn从sum(...)调用内部删除了方括号([])。这可以防止Python创建所有这些项的列表,而只是迭代它们,这可能会根据该列表的大小潜在地提高性能/内存。 - Jake Griffin

3
您还可以使用“or”运算符:
c['suspended_amount'] = sum([owned_license.charge_amount or 0 for owned_license in log.owned_licenses.all()])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接