【问题标题】:How to round to zero decimals if there is no decimal value with Jinja2?如果 Jinja2 没有十进制值,如何将小数四舍五入为零?
【发布时间】:2015-02-11 15:47:41
【问题描述】:

我使用(优秀的)Flask framework 构建了一个网站,我现在想在其中显示一些数字。 jinja2 提供的round filter 工作正常,除非没有十进制值:

{{ 1.55555|round(2) }} -> 1.56
{{ 1.5|round(2) }} -> 1.5
{{ 1.0|round(2) }} -> 1.0
{{ 1|round(2) }} -> 1.0

但我希望最后两个显示为1(没有尾随.0)。有人知道我如何用 jinja2 做到这一点吗?欢迎所有提示!

[编辑]

我尝试使用trim(),但令我惊讶的是,下面的 sn-p 给出了TypeError: do_trim() takes exactly 1 argument (2 given)

{{ 1.0|round(2)|trim('.0') }}

【问题讨论】:

  • 我认为你不能使用默认的 Jinja2 过滤器。在 Python 中使用Formatting floats in Python without superfluous zeros 进行操作,或者创建您自己的过滤器来实现它。
  • trim 只希望修剪的值作为参数。您不能指定要修剪的内容。
  • 警告! "|trim('.0')" 把 10.0 变成 1。

标签: python templates flask rounding jinja2


【解决方案1】:

你可以使用string filter,然后使用str.rstrip

>>> import jinja2
>>> print(jinja2.Template('''
... {{ (1.55555|round(2)|string).rstrip('.0') }}
... {{ (1.5|round(2)|string).rstrip('.0') }}
... {{ (1.0|round(2)|string).rstrip('.0') }}
... {{ (1|round(2)|string).rstrip('.0') }}
... ''').render())

1.56
1.5
1
1

注意

使用str.rstrip,您将得到0 的空字符串。

>>> jinja2.Template('''{{ (0|round(2)|string()).strip('.0') }}''').render()
u''

这是避免上述情况的解决方案(两次致电rstrip;一次与0,一次与.

>>> print(jinja2.Template('''
... {{ (1.55555|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (1.5|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (1.0|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (1|round(2)|string).rstrip('0').rstrip('.') }}
... {{ (0|round(2)|string).rstrip('0').rstrip('.') }}
... ''').render())

1.56
1.5
1
1
0

更新 以上代码会将10 修剪为1。以下代码没有问题。使用format filter

>>> print(jinja2.Template('''
... {{ ("%.2f"|format(1.55555)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(1.5)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(1.5)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(1.0)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(0)).rstrip('0').rstrip('.') }}
... {{ ("%.2f"|format(10)).rstrip('0').rstrip('.') }}
... ''').render())

1.56
1.5
1.5
1
0
10

【讨论】:

  • 太棒了!奇迹般有效!如果您也有空字符串问题的解决方案,那就更棒了.. :)
  • 这会将10 修剪为1
  • @kennysong,感谢您的评论。我添加了另一个解决方案,但没有您提到的问题。
【解决方案2】:

如果你要经常使用这个,我认为最好写一个自定义过滤器来避免混乱,像这样:

from jinja2 import filters

def myround(*args, **kw):
    # Use the original round filter, to deal with the extra arguments
    res = filters.do_round(*args, **kw)
    # Test if the result is equivalent to an integer and
    # return depending on it
    ires = int(res)
    return (res if res != ires else ires)

注册它,你就完成了。交互式解释器中的示例:

>>> from jinja2 import Environment
>>> env = Environment()
>>> env.filters['myround'] = myround
>>> env.from_string("{{ 1.4|myround(2) }}").render()
u'1.4'
>>> env.from_string("{{ 1.4|myround }}").render()
u'1'
>>> env.from_string("{{ 0.3|myround }}").render()
u'0'

【讨论】:

    【解决方案3】:

    更好的解决方案,避免60.0变成6,0.0变成空

    代替:

    (( YOURNUMBER )|string).rstrip('0')
    

    这样做:

    (( YOURNUMBER )|string )[:-2]
    

    这将切断字符串的最后 2 个字符。由于 round(0) 总是产生一个以 .0 结尾的数字,这将很好地解决问题。

    【讨论】:

      【解决方案4】:

      你总是可以的

      {{ ((1|round(2))|string).split('.')[0] }}
      

      流程分解:

      1. 1|round(2) -> 1.0
      2. |string 会将输出转换为字符串,以便我们可以使用 split()
      3. .split('.') 将使用 . 分隔符分割字符串 -> ["1", "0"]
      4. 由于.split()返回一个数组,[0]之后会得到第0个位置的字符串->“1”
      5. [可选] 如果您希望结果的数据类型为数字,则在末尾执行|int

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-12
        相关资源
        最近更新 更多