Python 数值中的下划线是怎么回事?

简介: Python 数值中的下划线是怎么回事?


概要和原理

本 PEP 提议扩展 Python 的语法,使得在“字符串变成数”(number-from-string)构造器中,下划线可以作为视觉分隔符,对整数、浮点和复数字面量的数字进行分组。

(Python猫注:关于 Python 的数值类型,可以查看 PEP-3141

这是其它现代语言的一个常见特性,有助于理解长的或者值应该被直观地分成几部分的字面量,如十六进制表示法中的字节或单词。

例子:

# grouping decimal numbers by thousands
amount = 10_000_000.0
# grouping hexadecimal addresses by words
addr = 0xCAFE_F00D
# grouping bits into nibbles in a binary literal
flags = 0b_0011_1111_0100_1110
# same, for string conversions
flags = int('0b_1111_0000', 2)

规范

目前的提议是在数字之间和在数字字面量的基本标识符之后,允许有一个下划线。下划线没有语义上的意义,数字字面量会被解析得就像没有下划线一样。

字面量语法

因此,整型字面量的表示法看起来像这样:

integer: decinteger | bininteger | octinteger | hexinteger
decinteger: nonzerodigit (["_"] digit)* | "0" (["_"] "0")*
bininteger: "0" ("b" | "B") (["_"] bindigit)+
octinteger: "0" ("o" | "O") (["_"] octdigit)+
hexinteger: "0" ("x" | "X") (["_"] hexdigit)+
nonzerodigit: "1"..."9"
digit: "0"..."9"
bindigit: "0" | "1"
octdigit: "0"..."7"
hexdigit: digit | "a"..."f" | "A"..."F"

浮点数和复数的字面量:

floatnumber: pointfloat | exponentfloat
pointfloat: [digitpart] fraction | digitpart "."
exponentfloat: (digitpart | pointfloat) exponent
digitpart: digit (["_"] digit)*
fraction: "." digitpart
exponent: ("e" | "E") ["+" | "-"] digitpart
imagnumber: (floatnumber | digitpart) ("j" | "J")

构造函数

遵循相同的放置规则,下划线可以在以下构造函数中使用:

  • int()(任意进制)
  • float()
  • complex()
  • Decimal()

进一步的变更

新式的数字转字符串(number-to-string)格式化语法将被扩展,允许 _ 作为千位分隔符。这可以用更具可读性的字面量来轻松地生成代码。[11]

The syntax would be the same as for the comma, e.g. {:10_} for a width of 10 with _ separator.(这句没看懂...不译)

对于 b、x 和 o 格式符,_ 也将支持,并按 4 位数分组。

现有的技术

那些允许下划线分组的语言,实现了大量放置下划线的规则。在语言规范与实际行为相矛盾的情况下,以下会列出实际的行为。(“单个”或“多个”指的是允许多少连续的下划线。)

  • Ada:单个,仅在数字间 [8]
  • C# (7.0 版本的提案):多个,仅在数字间 [6]
  • C++14:单个,在数字之间(选了其它分隔符) [1]
  • D:多个,任意位置,包括末尾 [2]
  • Java:多个,仅在数字间 [7]
  • Julia:单个,仅在数字间(但不含浮点指数部分) [9]
  • Perl 5:多个,基本是任意位置,尽管文档说数字间限制 1 个下划线 [3]
  • Ruby:单个,仅在数字间(尽管文档说“任意位置”)[10]
  • Rust:多个,任意位置,除了指数“e”与数字间 [4]
  • Swift:多个,数字之间和末尾(尽管文档说仅在“数字之间”) [5]

被否决的语法

(Python猫注:每个 PEP 在初提出阶段,都可能引起很多关于语法设计的讨论,在正式采纳的 PEP 中,一般会保留一些有代表性的被否决的方案,例如下面的两项)

1、下划线的放置规则

减少下划线的使用限制,而不是上面声明的相对严格的规则。在其它语言中,常见的规则包括:

  • 只允许一个连续的下划线,并且只能在数字之间。
  • 允许多个连续的下划线,但只能在数字之间。
  • 允许多个连续的下划线,在大多数位置,除了字面量的开头,或特殊的位置(例如小数点后)。

本 PEP 中的语法最终被选中,因为它涵盖了常见的用例,并且不会出现被 Python 风格指南所不鼓励使用的语法。

一个不太常见的规则是只允许每 N 位数字有下划线(其中 N 可能是 3 个十进制字面量,或 4 个十六进制字面量)。这是不必要的限制,特别是考虑到这些分隔符位置在不同的文化中是不同的。(Python猫注:例如,我们国家习惯将 4 个数字分为一组,即 10000 是 1 万,而不是英语文化中的 10 thousand)

2、其它的分隔符

还有一种建议是使用空格进行分组。虽然字符串是一种结合相邻字面量的先例,但这种行为可能会导致意外的效果,而下划线则不会。而且,除了那些基本会忽略任何空格的语言外,没有其它语言使用此规则。

c++ 14 引入了单引号来进行分组(因为下划线会与用户定义的字面量产生歧义),由于单引号已经被 Python 的字符串字面量使用了,所以没有考虑它。[1]

实现

实现上述规范的初步补丁已经发布到问题跟踪器。[12]

参考内容

[1] (1, 2) www.open-std.org/jtc1/sc22/w…

[2] dlang.org/spec/lex.ht…

[3] perldoc.perl.org/perldata#Sc…

[4] web.archive.org/web/2016030…

[5] docs.swift.org/swift-book/…

[6] github.com/dotnet/rosl…

[7] docs.oracle.com/javase/7/do…

[8] archive.adaic.com/standards/8…

[9] web.archive.org/web/2016022…

[10] ruby-doc.org/core-2.3.0/…

[11] mail.python.org/pipermail/p…

[12] bugs.python.org/issue26331

版权

该文档已放入公共领域。

源文件:github.com/python/peps…

目录
相关文章
|
4月前
|
BI C语言 索引
Python科学计算库Numpy数值运算基础详解(超详细 附源码)
Python科学计算库Numpy数值运算基础详解(超详细 附源码)
60 0
|
4月前
|
索引 Python
Python 中的单下划线和双下划线
Python 中的单下划线和双下划线
|
1月前
|
索引 Python
在Python中创建数值列表
在Python中创建数值列表
18 1
|
2月前
|
存储 编解码 Python
Python GDAL基于经、纬度提取大量遥感影像中相同位置处像元的数值
【2月更文挑战第8天】本文介绍基于Python语言中的gdal模块,对2景不同的遥感影像加以对应位置像素值匹配的方法——即基于一景遥感影像的每一个像元,提取另一景遥感影像中,与之空间位置相同的像元的像素值的方法~
Python GDAL基于经、纬度提取大量遥感影像中相同位置处像元的数值
|
6月前
|
Python
【Python】【Pandas】将符合条件行的某列数值改为负数
在此顺便记录几个常用代码写法: 1.不重复取出一列的值data[列名].unique()或者data[列名].value_counts(sort=False) 2.对取出的列值进行格式处理
82 0
|
2月前
|
Python
在Python中计算一组数值数据的中位数
在Python中计算一组数值数据的中位数
40 2
|
3月前
|
Java Go C++
Golang每日一练(leetDay0110) 零钱兑换I\II Coin Change
Golang每日一练(leetDay0110) 零钱兑换I\II Coin Change
39 0
Golang每日一练(leetDay0110) 零钱兑换I\II Coin Change
|
3月前
|
Python Java Go
Python每日一练(20230409) 字符串拆分数值求和、快乐数、格雷编码
Python每日一练(20230409) 字符串拆分数值求和、快乐数、格雷编码
42 0
Python每日一练(20230409) 字符串拆分数值求和、快乐数、格雷编码
|
4月前
|
定位技术 Python
Python中GDAL基于栅格影像叠加提取另一景栅格影像的像元数值
Python中GDAL基于栅格影像叠加提取另一景栅格影像的像元数值
|
4月前
|
机器学习/深度学习 数据处理 索引
Python下数值型与字符型类别变量独热编码(One-hot Encoding)实现
Python下数值型与字符型类别变量独热编码(One-hot Encoding)实现