문자열에 0을 채우는 방법?


답변:


2390

문자열 :

>>> n = '4'
>>> print(n.zfill(3))
004

그리고 숫자의 경우 :

>>> n = 4
>>> print(f'{n:03}') # Preferred method, python >= 3.6
004
>>> print('%03d' % n)
004
>>> print(format(n, '03')) # python >= 2.6
004
>>> print('{0:03d}'.format(n))  # python >= 2.6 + python 3
004
>>> print('{foo:03d}'.format(foo=n))  # python >= 2.6 + python 3
004
>>> print('{:03d}'.format(n))  # python >= 2.7 + python3
004

문자열 형식화 문서 .


3
'float'유형의 오브젝트에 대해 알 수없는 형식 코드 'd'.
Cees Timmerman 2016 년

7
댓글 python >= 2.6이 잘못되었습니다. 해당 구문은 작동하지 않습니다 python >= 3. 로 변경할 수는 python < 3있지만 대신 항상 괄호를 사용하고 주석을 모두 생략하는 것이 좋습니다 (권장되는 사용법 권장)?
Jason R. Coombs

4
형식 문자열에 번호를 매길 필요는 없습니다 '{:03d} {:03d}'.format(1, 2). 값을 암시 적으로 순서대로 할당합니다.
Dragon

1
@ JasonR.Coombs : 파이썬 3 print에서 print함수 가되어야 할 때 진술 을 의미한다고 가정 합니까? 나는 파 렌스에서 편집했다. 한 가지만 인쇄되기 때문에 Py2와 Py3에서 동일하게 작동합니다.
ShadowRanger


353

문자열 객체 의 rjust 메소드를 사용하십시오 .

이 예에서는 필요에 따라 10 자 길이의 문자열을 채 웁니다.

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

123

게다가 zfill일반적인 문자열 형식을 사용할 수 있습니다.

print(f'{number:05d}') # (since Python 3.6), or
print('{:05d}'.format(number)) # or
print('{0:05d}'.format(number)) # or (explicit 0th positional arg. selection)
print('{n:05d}'.format(n=number)) # or (explicit `n` keyword arg. selection)
print(format(number, '05d'))

문자열 형식f- 문자열에 대한 설명서 .


3
PEP 3101은 %가 더 이상 사용되지 않는다고 명시하지 않습니다.
zwirbeltier

@zwirbeltier PEP 3101은 형식을 사용하는 방법을 설명합니다.
Konrad Rudolph

4
"EDIT"는 여전히 "…이 형식 지정 방법은 사용되지 않습니다…"라고 표시합니다.
zwirbeltier

1
@zwirbeltier 예, 더 이상 사용되지 않습니다. 그러나 이것은 PEP에 직접 언급되어 있지 않습니다. 그러나 문서는 format대신 사용한다고 말하고 사람들은 일반적으로 이것을 사용하지 않을 의도로 해석합니다.
Konrad Rudolph

1
@LarsH 이것을 찾아 주셔서 감사합니다. 그래서 그들은 일정이 심각하지 않습니다 (Python 3.1은 미래가 아니며 먼 과거에 있습니다). 그 점을 감안할 때, 파이썬 개발 일정이 새로운 임의의 방향으로 바뀔 때마다 엄격하게 업데이트되지 않은 대답은 오해의 소지가 없다고 생각합니다. 어쨌든, 이것은 내 대답에서 관련이없고 오래된 것들을 제거 할 수있는 기회를주었습니다.
Konrad Rudolph

63

f- 문자열을 사용하는 Python 3.6 이상 :

>>> i = 1
>>> f"{i:0>2}"  # Works for both numbers and strings.
'01'
>>> f"{i:02}"  # Works only for numbers.
'01'

Python 2에서 Python 3.5까지 :

>>> "{:0>2}".format("1")  # Works for both numbers and strings.
'01'
>>> "{:02}".format(1)  # Works only for numbers.
'01'

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

당신이 반대를 원한다면 :

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

39

str(n).zfill(width)strings, ints, floats ...와 함께 작동하며 Python 2 x 및 3입니다. x 호환 가능 :

>>> n = 3
>>> str(n).zfill(5)
'00003'
>>> n = '3'
>>> str(n).zfill(5)
'00003'
>>> n = '3.0'
>>> str(n).zfill(5)
'003.0'

23

여기에 온 사람들은 단지 빠른 대답이 아니라 이해하기 위해서입니다. 나는 특히 시간 문자열을 위해 이것을한다 :

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


23

숫자 문자열을 왼쪽으로 0으로 채우는 가장 파이썬적인 방법은 무엇입니까? 즉 숫자 문자열의 길이는 얼마입니까?

str.zfill 이를 위해 특별히 고안되었습니다.

>>> '1'.zfill(4)
'0001'

요청에 따라 숫자 문자열을 처리하기 위해 특별히 고안되었으며 a +또는 -문자열의 시작 부분으로 이동 합니다.

>>> '+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

이행

약간의 파기를 통해 zfill메소드 구현을 다음과 같이 발견 했습니다 Objects/stringlib/transmogrify.h.

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'

성능을 위해 python2 대 python3의 사용 사례를 포함하여 f 문자열이 더 나은 경우가 있습니까? 또한 zfill은 일반적이지 않기 때문에 귀하의 답변이 문서와 연결되는 데 도움이 될 것입니다.
elad silver

@eladsilver는의 의도에 따라 +및 의 동작을 염두에두고 -문서에 대한 링크를 추가했습니다.
Aaron Hall

17
width = 10
x = 5
print "%0*d" % (width, x)
> 0000000005

모든 흥미로운 세부 사항은 인쇄 설명서를 참조하십시오!

Python 3.x 업데이트 (7.5 년 후)

마지막 줄은 이제 다음과 같아야합니다.

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

print(), 이제는 문장이 아닌 함수입니다. printf()IMNSHO는 더 잘 읽히고 1980 년 1 월 이후로 그 표기법을 사용했기 때문에 Old School 스타일을 선호합니다 .


1980 년 이후로 ... 60 세의 프로그래머 "%0*d" % (width, x)입니까? 파이썬 으로 어떻게 해석 되는지 더 자세히 설명해 주 시겠습니까?
Lee

15

파이썬을 사용하는 경우 >= 3.6, 가장 깨끗한 방법은 사용하는 F-문자열문자열 서식 :

>>> s = f"{1:08}"  # inline with int
>>> s
'00000001'
>>> s = f"{'1':0>8}"  # inline with str
>>> s
'00000001'
>>> n = 1
>>> s = f"{n:08}"  # int variable
>>> s
'00000001'
>>> c = "1"
>>> s = f"{c:0>8}"  # str variable
>>> s
'00000001'

int부호 만 올바르게 처리되기 때문에으로 서식을 지정하는 것이 좋습니다.

>>> f"{-1:08}"
'-0000001'

>>> f"{1:+08}"
'+0000001'

>>> f"{'-1':0>8}"
'000000-1'

새로운 구문 예제에 감사드립니다. 채우기 문자 'x'는 다음과 같습니다. v = "A18"; s = f '{v : x> 8}'+ "|"; 또는 s = v.ljust (8, "x") + "|";
Charlie 木匠

@Charlie 木匠 저에게 질문입니까, 아니면 그냥 진술입니까?
ruohola

단지 진술. 더 많은 사용법을 테스트했습니다.
Charlie 木匠

4

정수로 저장된 우편 번호 :

>>> a = 6340
>>> b = 90210
>>> print '%05d' % a
06340
>>> print '%05d' % b
90210

1
당신은 정확하고, 나는 zfill에 대한 당신의 제안이 어쨌든 더 좋습니다

3

빠른 타이밍 비교 :

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솔루션이 가장 빠릅니다.


1

다른 접근법은 길이를 점검하는 조건과 함께 목록 이해를 사용하는 것입니다. 아래는 데모입니다.

# input list of strings that we want to prepend zeros
In [71]: list_of_str = ["101010", "10101010", "11110", "0000"]

# prepend zeros to make each string to length 8, if length of string is less than 8
In [83]: ["0"*(8-len(s)) + s if len(s) < desired_len else s for s in list_of_str]
Out[83]: ['00101010', '10101010', '00011110', '00000000']

0

그것도 괜찮습니다 :

 h = 2
 m = 7
 s = 3
 print("%02d:%02d:%02d" % (h, m, s))

출력은 "02:07:03"입니다.


-2

"0"을 반복하여 앞에 붙여서 str(n)가장 오른쪽에있는 슬라이스를 얻을 수도 있습니다. 빠르고 더러운 작은 표현.

def pad_left(n, width, pad="0"):
    return ((pad * width) + str(n))[-width:]

1
이것은 양수에만 적용됩니다. 네거티브도 원하면 조금 더 복잡해집니다. 그러나 이런 표현은 마음에 들지 않으면 빠르고 더러운 작업에 좋습니다.
J Lacar

나는 이것이 왜 다운 보트인지 전혀 모른다. 그것이 원인이라면 충분히 음수에서는 작동하지 않지만 0으로 채워진 압도적 인 이유는 id 숫자입니다. 음수 ID 번호가 있다면 더 큰 문제가 있다고 생각합니다. 패드가 '00000-1234'형식 일 것으로 예상하십니까? 또는 '-000001234'? 솔직히이 대답이 효과가있는 질문이 주어지면 간단하고 깨끗하며 확장 가능합니다. 그것은 zfill이 아닐 수도 있지만 질문에 대답하면 upvoted해야합니다.
TastySlowCooker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.