如何在数字字符串的左边加上零,使字符串具有特定的长度?


当前回答

只需使用字符串对象的rjust方法。

此示例创建一个10个字符长度的字符串,根据需要进行填充:

>>> s = 'test'
>>> s.rjust(10, '0')
>>> '000000test'

其他回答

只需使用字符串对象的rjust方法。

此示例创建一个10个字符长度的字符串,根据需要进行填充:

>>> s = 'test'
>>> s.rjust(10, '0')
>>> '000000test'
width = 10
x = 5
print "%0*d" % (width, x)
> 0000000005

有关所有令人兴奋的详细信息,请参阅打印文档!

Python 3.x更新(7.5年后)

最后一行现在应该是:

print("%0*d" % (width, x))

即print()现在是一个函数,而不是一个语句。注意,我仍然更喜欢Old School printf()风格,因为IMNSHO,它读起来更好,而且,嗯,我从1980年1月起就一直使用这种符号。某物老狗。。一些东西。。。新技巧。

对于那些来这里理解而不仅仅是快速回答的人来说。我特别针对时间字符串:

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

>>> '99'.zfill(5)
'00099'
>>> '99'.rjust(5,'0')
'00099'

如果你想要相反的:

>>> '99'.ljust(5,'0')
'99000'

哪种最适合用零填充数字字符串,即数字字符串具有特定长度?

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方法的实现:

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调用)。这基本上将内容复制到一个新字符串中并填充填充。

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'