ipython:用千位分隔符打印数字

如何解决ipython:用千位分隔符打印数字

我在 ipython 上使用 5.8.0 Debian 10

输出结果如下:

In [1]: 50*50
Out[1]: 2500

是否可以配置 ipython 以使用千位分隔符打印所有数字?即:

In [1]: 50*50
Out[1]: 2'500

In [2]: 5000*5000
Out[2]: 25'000'000

也许,是否可以让 ipython 也理解输入的千位分隔符?

In [1]: 5'000*5'000
Out[1]: 25'000'000

更新

来自 @Chayim Friedman 的公认答案适用于整数,但不适用于浮点数:

In [1]: 500.1*500
Out[1]: 250050.0

另外,当它工作时,它使用 , 作为千位分隔符的字符:

In [1]: 500*500
Out[1]: 250,000

我可以改用 ' 吗?

解决方法

在输入中使用 ' 作为千位分隔符是很成问题的,因为 Python 使用 ' 来分隔字符串,但您可以使用 _ (PEP 515,Underscores in Numeric Literals):

IPython input thousand separators

关于输出,这有点难,但可以使用 IPython 扩展来完成。

将以下 Python 代码放在 ~/.ipython/extensions/thousands_separator.py 的新文件中:

default_int_printer = None

def print_int(number,printer,cycle):
    printer.text(f'{number:,}') # You can use `'{:,}'.format(number)` if you're using a Python version older than 3.6

def load_ipython_extension(ipython):
    global default_int_printer

    default_int_printer = ipython.display_formatter.formatters['text/plain'].for_type(int,print_int)

def unload_ipython_extension(ipython):
    ipython.display_formatter.formatters['text/plain'].for_type(int,default_int_printer)

此代码告诉 IPython 将默认的 int 格式化程序替换为在加载此扩展时打印千位分隔符的格式化程序,并在卸载时恢复原始格式。

编辑:如果您想要不同的分隔符,例如 ',请将 f'{number:,}' 替换为 f'{number:,}'.replace(',',"'")

您可以使用魔法命令 %load_ext thousands_separator 加载扩展程序并使用 %unload_ext thousands_separator 卸载它,但如果您总是想要它,您可以将它放在默认配置文件中。

在终端中运行以下代码:

ipython3 profile create

它会报告一个文件 ~/.ipython/profile_default/ipython_config.py 被创建。输入它,然后搜索以下字符串:

## A list of dotted module names of IPython extensions to load.
#c.InteractiveShellApp.extensions = []

将其替换为以下内容:

# A list of dotted module names of IPython extensions to load.
c.InteractiveShellApp.extensions = [
    'thousands_separator'
]

这告诉 IPython 默认加载这个扩展。

完成!

enter image description here

编辑:我看到你想 a) 使用 ' 作为分隔符,b) 对浮点数做同样的事情:

使用不同的分隔符非常简单:只需 str.replace():

def print_int(number,"'"))

对浮点数做同样的事情也很简单:只需设置 print_int 以便将浮点数打印到。我还建议将名称更改为 print_number

最终代码:

default_int_printer = None
default_float_printer = None

def print_number(number,"'"))

def load_ipython_extension(ipython):
    global default_int_printer
    global default_float_printer

    default_int_printer = ipython.display_formatter.formatters['text/plain'].for_type(int,print_number)
    default_float_printer = ipython.display_formatter.formatters['text/plain'].for_type(float,print_number)

def unload_ipython_extension(ipython):
    ipython.display_formatter.formatters['text/plain'].for_type(int,default_int_printer)
    ipython.display_formatter.formatters['text/plain'].for_type(float,default_float_printer)
,

更新后:你可以子类化int:

class Int(int):
    def __repr__(self):
        return "{:,}".format(self)
Int(1000)
# 1,000
,

我不相信您可以在不重写 iPython 解释器的情况下实现您正在寻找的所有,这意味着更改 Python 语言规范,以便能够输入带有嵌入 {{1} } 字符并忽略它们。但是你可以实现其中的一些。子类化 ' 类是一个好的开始。但是您还应该重载您计划使用的各种运算符。例如:

int

打印:

class Integer(int):
    def __str__(self):
        # if you want ' as the separator:
        return "{:,}".format(self).replace(",","'")

    def __add__(self,x):
        return Integer(int(self) + x)

    def __mul__(self,x):
        return Integer(int(self) * x)

    """
    define other operations: __sub__,__floordiv__,__mod__,__neg__,etc.
    """


i1 = Integer(2)
i2 = Integer(1000) + 4.5 * i1
print(i2)
print(i1 * (3 + i2))

更新

似乎对于 Python 3.7,您需要覆盖 1'009 2'024 方法而不是 __str__ 方法。这适用于 Python 3.8,也适用于更高版本。

更新 2

__repr__

打印:

import locale

#locale.setlocale(locale.LC_ALL,'') # probably not required
print(locale.format_string("%d",1255000,grouping=True).replace(","'"))

如果您有来自 Babel 存储库的包 PyPi,则另一种选择:

1'255'000

打印:

from babel import Locale
from babel.numbers import format_number

locale = Locale('en','US')
locale.number_symbols['group'] = "'"

print(format_number(1255000,locale='en_US'))

或者,如果您更喜欢为此目的定制语言环境,并且不修改标准 1'255'000 语言环境。 这也显示了如何解析输入值:

en_US

打印:

from copy import deepcopy
from babel import Locale
from babel.numbers import format_number,parse_number

my_locale = deepcopy(Locale('en','US'))
my_locale.number_symbols['group'] = "'"
print(format_number(1255000,locale=my_locale))
print(parse_number("1'125'000",locale=my_locale))
,

基于PEP-0378,可以使用如下代码:

a = 1200
b = 500
c = 10

#res = a
#res = a*b
res = a*b*c

dig = len(str(res))       # to figure out how many digits are required in result
print(format(res,"{},d".format(dig)))

它将产生:

6,000,000

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?