使用零填充数字字符串的最Pythonic方法是什么,即数字字符串是否具有特定长度?
字符串:
>>> n = '4' >>> print n.zfill(3) 004
对于数字:
>>> n = 4 >>> print '%03d' % n 004 >>> print format(n, '03') # python >= 2.6 004 >>> print '{0:03d}'.format(n) # python >= 2.6 004 >>> print '{foo:03d}'.format(foo=n) # python >= 2.6 004 >>> print('{:03d}'.format(n)) # python >= 2.7 + python3 004 >>> print('{0:03d}'.format(n)) # python 3 004 >>> print(f'{n:03}') # python >= 3.6 004
String formatting documentation .
只需使用字符串对象的rjust方法即可 .
这个例子将生成一个10个字符长的字符串,根据需要填充 .
>>> t = 'test' >>> t.rjust(10, '0') >>> '000000test'
print "%05d" % number
另见:Python: String formatting .
EDIT :值得注意的是,截至2008年12月3日,这种格式化方法已弃用,而采用 format 字符串方法:
format
print("{0:05d}".format(number)) # or print(format(number, "05d"))
有关详细信息,请参阅PEP 3101 .
>>> '99'.zfill(5) '00099' >>> '99'.rjust(5,'0') '00099'
如果你想要相反:
>>> '99'.ljust(5,'0') '99000'
适用于Python 2和Python 3:
>>> "{:0>2}".format("1") # Works for both numbers and strings. '01' >>> "{:02}".format(1) # Only works for numbers. '01'
str(n).zfill(width) 将适用于 string s, int s, float s ...并且兼容Python 2.x和3.x:
str(n).zfill(width)
string
int
float
>>> n = 3 >>> str(n).zfill(5) '00003' >>> n = '3' >>> str(n).zfill(5) '00003' >>> n = '3.0' >>> str(n).zfill(5) '003.0'
对于那些来这里了解而不仅仅是快速回答的人 . 我特别为时间字符串做这些:
hour = 4 minute = 3 "{:0>2}:{:0>2}".format(hour,minute) # prints 04:03 "{:0>3}:{:0>5}".format(hour,minute) # prints '004:00003' "{:0<3}:{:0<5}".format(hour,minute) # prints '400:30000' "{:$<3}:{:#<5}".format(hour,minute) # prints '4$$:3####'
“0”符号用“2”填充字符替换,默认为空格“>”符号将字符串左边的所有2“0”字符对齐“:”符号format_spec
width = 10 x = 5 print "%0*d" % (width, x) > 0000000005
有关所有令人兴奋的细节,请参阅打印文档!
Update for Python 3.x (7.5 years later)
最后一行现在应该是:
print("%0*d" % (width, x))
即 print() 现在是一个函数,而不是一个声明 . 请注意,我仍然更喜欢Old School printf() 风格,因为,IMNSHO,它读起来更好,因为,嗯,我自1980年1月以来一直在使用那种符号 . 某些东西......老狗......某事......新技巧 .
print()
printf()
使用零填充数字字符串的最pythonic方法是什么,即数字字符串是否具有特定长度?
str.zfill 专门用于执行此操作:
str.zfill
>>> '1'.zfill(4) '0001'
请注意,它专门用于处理请求的数字字符串,并将 + 或 - 移动到字符串的开头:
+
-
>>> '+1'.zfill(4) '+001' >>> '-1'.zfill(4) '-001'
这是 str.zfill 的帮助:
>>> help(str.zfill) Help on method_descriptor: zfill(...) S.zfill(width) -> str Pad a numeric string S with zeros on the left, to fill a field of the specified width. The string S is never truncated.
这也是替代方法中性能最高的方法:
>>> min(timeit.repeat(lambda: '1'.zfill(4))) 0.18824880896136165 >>> min(timeit.repeat(lambda: '1'.rjust(4, '0'))) 0.2104538488201797 >>> min(timeit.repeat(lambda: f'{1:04}')) 0.32585487607866526 >>> min(timeit.repeat(lambda: '{:04}'.format(1))) 0.34988890308886766
为了最佳地比较 % 方法的苹果与苹果(注意它实际上较慢),否则将预先计算:
%
>>> min(timeit.repeat(lambda: '1'.zfill(0 or 4))) 0.19728074967861176 >>> min(timeit.repeat(lambda: '%04d' % (0 or 1))) 0.2347015216946602
通过一点挖掘,我在Objects/stringlib/transmogrify.h中找到了 zfill 方法的实现:
zfill
static PyObject * stringlib_zfill(PyObject *self, PyObject *args) { Py_ssize_t fill; PyObject *s; char *p; Py_ssize_t width; if (!PyArg_ParseTuple(args, "n:zfill", &width)) return NULL; if (STRINGLIB_LEN(self) >= width) { return return_self(self); } fill = width - STRINGLIB_LEN(self); s = pad(self, fill, 0, '0'); if (s == NULL) return NULL; p = STRINGLIB_STR(s); if (p[fill] == '+' || p[fill] == '-') { /* move sign to beginning of string */ p[0] = p[fill]; p[fill] = '0'; } return s; }
让我们来看看这个C代码 .
它首先在位置上解析参数,这意味着它不允许关键字参数:
>>> '1'.zfill(width=4) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: zfill() takes no keyword arguments
然后检查它是否长度相同或更长,在这种情况下它返回字符串 .
>>> '1'.zfill(0) '1'
zfill 调用 pad (此 pad 函数也由 ljust , rjust 和 center 调用) . 这基本上将内容复制到一个新字符串并填充填充 .
pad
ljust
rjust
center
static inline PyObject * pad(PyObject *self, Py_ssize_t left, Py_ssize_t right, char fill) { PyObject *u; if (left < 0) left = 0; if (right < 0) right = 0; if (left == 0 && right == 0) { return return_self(self); } u = STRINGLIB_NEW(NULL, left + STRINGLIB_LEN(self) + right); if (u) { if (left) memset(STRINGLIB_STR(u), fill, left); memcpy(STRINGLIB_STR(u) + left, STRINGLIB_STR(self), STRINGLIB_LEN(self)); if (right) memset(STRINGLIB_STR(u) + left + STRINGLIB_LEN(self), fill, right); } return u; }
在调用 pad 之后, zfill 将任何原先前面的 + 或 - 移动到字符串的开头 .
请注意,对于原始字符串实际上是数字不是必需的:
>>> '+foo'.zfill(10) '+000000foo' >>> '-foo'.zfill(10) '-000000foo'
>>> width = 4 >>> x = 5 >>> print("%0*d" %(width,x)) >>> 00005
这将在python 3.x中工作
对于保存为整数的邮政编码:
>>> a = 6340 >>> b = 90210 >>> print '%05d' % a 06340 >>> print '%05d' % b 90210
快速计时比较:
setup = ''' from random import randint def test_1(): num = randint(0,1000000) return str(num).zfill(7) def test_2(): num = randint(0,1000000) return format(num, '07') def test_3(): num = randint(0,1000000) return '{0:07d}'.format(num) def test_4(): num = randint(0,1000000) return format(num, '07d') def test_5(): num = randint(0,1000000) return '{:07d}'.format(num) def test_6(): num = randint(0,1000000) return '{x:07d}'.format(x=num) def test_7(): num = randint(0,1000000) return str(num).rjust(7, '0') ''' import timeit print timeit.Timer("test_1()", setup=setup).repeat(3, 900000) print timeit.Timer("test_2()", setup=setup).repeat(3, 900000) print timeit.Timer("test_3()", setup=setup).repeat(3, 900000) print timeit.Timer("test_4()", setup=setup).repeat(3, 900000) print timeit.Timer("test_5()", setup=setup).repeat(3, 900000) print timeit.Timer("test_6()", setup=setup).repeat(3, 900000) print timeit.Timer("test_7()", setup=setup).repeat(3, 900000) > [2.281613943830961, 2.2719342631547077, 2.261691106209631] > [2.311480238815406, 2.318420542148333, 2.3552384305184493] > [2.3824197456864304, 2.3457239951596485, 2.3353268829498646] > [2.312442972404032, 2.318053102249902, 2.3054072168069872] > [2.3482314132374853, 2.3403386400002475, 2.330108825844775] > [2.424549090688892, 2.4346475296851438, 2.429691196530058] > [2.3259756401716487, 2.333549212826732, 2.32049893822186]
我对不同的重复进行了不同的测试 . 差异并不大,但在所有测试中, zfill 解决方案最快 .
您也可以重复"0",将其添加到 str(n) 并获取最右边的宽度切片 . 快速而肮脏的小表达 .
str(n)
def pad_left(n, width, pad="0"): return ((pad * width) + str(n))[-width:]
13 回答
字符串:
对于数字:
String formatting documentation .
只需使用字符串对象的rjust方法即可 .
这个例子将生成一个10个字符长的字符串,根据需要填充 .
对于数字:
另见:Python: String formatting .
EDIT :值得注意的是,截至2008年12月3日,这种格式化方法已弃用,而采用
format
字符串方法:有关详细信息,请参阅PEP 3101 .
如果你想要相反:
适用于Python 2和Python 3:
str(n).zfill(width)
将适用于string
s,int
s,float
s ...并且兼容Python 2.x和3.x:对于那些来这里了解而不仅仅是快速回答的人 . 我特别为时间字符串做这些:
有关所有令人兴奋的细节,请参阅打印文档!
Update for Python 3.x (7.5 years later)
最后一行现在应该是:
即
print()
现在是一个函数,而不是一个声明 . 请注意,我仍然更喜欢Old Schoolprintf()
风格,因为,IMNSHO,它读起来更好,因为,嗯,我自1980年1月以来一直在使用那种符号 . 某些东西......老狗......某事......新技巧 .str.zfill
专门用于执行此操作:请注意,它专门用于处理请求的数字字符串,并将
+
或-
移动到字符串的开头:这是
str.zfill
的帮助:表现
这也是替代方法中性能最高的方法:
为了最佳地比较
%
方法的苹果与苹果(注意它实际上较慢),否则将预先计算:实施
通过一点挖掘,我在Objects/stringlib/transmogrify.h中找到了
zfill
方法的实现:让我们来看看这个C代码 .
它首先在位置上解析参数,这意味着它不允许关键字参数:
然后检查它是否长度相同或更长,在这种情况下它返回字符串 .
zfill
调用pad
(此pad
函数也由ljust
,rjust
和center
调用) . 这基本上将内容复制到一个新字符串并填充填充 .在调用
pad
之后,zfill
将任何原先前面的+
或-
移动到字符串的开头 .请注意,对于原始字符串实际上是数字不是必需的:
这将在python 3.x中工作
对于保存为整数的邮政编码:
快速计时比较:
我对不同的重复进行了不同的测试 . 差异并不大,但在所有测试中,
zfill
解决方案最快 .您也可以重复"0",将其添加到
str(n)
并获取最右边的宽度切片 . 快速而肮脏的小表达 .