कैसे एक स्ट्रिंग करने के लिए जीरो पैड?


1440

एक संख्यात्मक स्ट्रिंग को बाईं ओर शून्य के साथ पैड करने का एक पायथोनिक तरीका क्या है, इसलिए संख्यात्मक स्ट्रिंग की एक विशिष्ट लंबाई है?

जवाबों:


2389

स्ट्रिंग्स:

>>> 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
अज्ञात प्रारूप कोड 'd' टाइप 'फ्लोट' की वस्तु के लिए।
सेस टिम्मरमैन

7
टिप्पणियाँ python >= 2.6गलत हैं। उस वाक्य रचना पर काम नहीं करता है python >= 3। आप इसे बदल सकते हैं python < 3, लेकिन क्या मैं हमेशा कोष्ठक का उपयोग करने और टिप्पणियों को पूरी तरह से छोड़ने के बजाय सुझाव दे सकता हूं (अनुशंसित उपयोग को प्रोत्साहित करना)?
जेसन आर। कोम्ब्स

4
ध्यान दें कि आपको अपने प्रारूप स्ट्रिंग को '{:03d} {:03d}'.format(1, 2)क्रमांकित करने की आवश्यकता नहीं है: अंतर्निहित रूप से मानों को क्रम में निर्दिष्ट करता है।
ड्रैगन

1
@ JasonR.Cbs: मुझे लगता है कि आप printबयान का मतलब है , जब यह printपायथन 3 पर एक समारोह होना चाहिए ? मैंने पारेंस में संपादित किया; चूँकि केवल एक ही चीज़ मुद्रित हो रही है, यह Py2 और Py3 पर अब समान रूप से काम करता है।
शैडो रेंजर


353

बस स्ट्रिंग ऑब्जेक्ट की रूल विधि का उपयोग करें ।

यह उदाहरण आवश्यक के रूप में पैडिंग 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'))

स्ट्रिंग प्रारूपण और एफ- स्ट्रिंग के लिए प्रलेखन ।


3
PEP 3101 यह नहीं बताता है कि% किसी भी तरह से हटा दिया गया है।
zwirbeltier

@zwirbeltier PEP 3101 प्रारूप का उपयोग करने का तरीका बताता है, मेरा मतलब है।
कोनराड रूडोल्फ

4
"EDIT" अभी भी बताता है ... स्वरूपण की यह विधि पदावनत है ... "।
zwirbeltier

1
@zwirbeltier हाँ, और यह पदावनत है। लेकिन यह सीधे पीईपी में नहीं बताया गया है। हालाँकि, दस्तावेज़ीकरण formatइसके बजाय उपयोग करने के लिए कहता है , और लोग आमतौर पर इसे व्याख्या के इरादे के रूप में व्याख्या करते हैं।
कोनराड रुडोल्फ

1
@ लार्स इसे पाने के लिए धन्यवाद। इसलिए वे अनुसूची के पीछे गंभीर रूप से हैं (पायथन 3.1 भविष्य में नहीं है, यह सबसे दूर अतीत में है)। यह देखते हुए, मुझे अभी भी नहीं लगता है कि उत्तर भ्रामक था, बस कड़ाई से हर बार अद्यतन नहीं किया गया जब पायथन विकास अनुसूची एक नई, मनमानी दिशा में बदल गई। वैसे भी, इससे मुझे अपने जवाब से कुछ अप्रासंगिक और पुरानी चीजें हटाने का मौका मिला।
कोनराड रुडोल्फ

62

पायथन 3.6+ के लिए f- स्ट्रिंग्स का उपयोग कर:

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

पायथन 2 से पायथन 3.5 के लिए:

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


39

str(n).zfill(width)strings, ints, floats के साथ काम करेगा ... और पायथन 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

शून्य से बायीं ओर एक संख्यात्मक स्ट्रिंग को पैड करने का सबसे पायथोनिक तरीका क्या है, इसलिए संख्यात्मक स्ट्रिंग की एक विशिष्ट लंबाई है?

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

कार्यान्वयन

थोड़ी खुदाई के साथ, मुझे इस 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'

प्रदर्शन के लिए, क्या ऐसे मामले हैं जहां f स्ट्रिंग्स python2 बनाम python3 के उपयोग मामलों सहित बेहतर हैं? मुझे यह भी लगता है कि zfill आम नहीं है, यह आपके उत्तर को डॉक्स के लिए लिंक करने में मदद करेगा
elad silver

@eladsilver आपके इरादे पर निर्भर करता है, के साथ व्यवहार को ध्यान में रखते हुए +और -, और मैंने डॉक्स के लिए एक लिंक जोड़ा!
हारून हॉल

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

सभी रोमांचक विवरणों के लिए प्रिंट प्रलेखन देखें!

पायथन 3.x के लिए अद्यतन (7.5 वर्ष बाद)

वह अंतिम पंक्ति अब होनी चाहिए:

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

Ie print()अब एक फंक्शन है, स्टेटमेंट नहीं। ध्यान दें कि मैं अभी भी पुराने स्कूल printf()शैली को पसंद करता हूं, क्योंकि, IMNSHO, यह बेहतर पढ़ता है, और क्योंकि, उम, मैं जनवरी, 1980 के बाद से उस अंकन का उपयोग कर रहा हूं। कुछ ... पुराने कुत्ते .. कुछ कुछ ... नई चालें।


1980 के बाद से ... तो क्या आप 60 साल के प्रोग्रामर हैं ... क्या आप "%0*d" % (width, x)अजगर द्वारा व्याख्या कैसे की जा सकती है?
ली

15

पायथन का उपयोग करते समय >= 3.6, सबसे बेहतर तरीका स्ट्रिंग प्रारूपण के साथ एफ-स्ट्रिंग्स का उपयोग करना है :

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

नए वाक्यविन्यास उदाहरण के लिए धन्यवाद। fill char 'x' होगा: v = "A18"; s = f '{v: x> 8}' + "|"; या s = v.ljust (8, "x") + "|";
चार्ली Char

@Charlie 木匠 क्या मेरे लिए एक सवाल था या सिर्फ एक बयान?
रूबल

सिर्फ एक बयान। कुछ और उपयोग का परीक्षण किया।
चार्ली Char

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]

मैंने अलग-अलग repetitions के विभिन्न परीक्षण किए हैं। अंतर बहुत बड़ा नहीं है, लेकिन सभी परीक्षणों में, 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
यह केवल सकारात्मक संख्याओं के लिए काम करता है। यदि आप नकारात्मक भी चाहते हैं तो यह थोड़ा अधिक जटिल हो जाता है। लेकिन यह अभिव्यक्ति त्वरित और गंदे काम के लिए अच्छी है, अगर आप उस तरह की बात नहीं करते हैं।
जे लैकर

मुझे इस बात का बिलकुल भी अंदाजा नहीं है कि इसे क्यों डाउन किया गया है। यदि यह कारण है कि यह नकारात्मक संख्याओं पर पर्याप्त रूप से काम नहीं करता है, लेकिन ज़ीरो के साथ पैड को छोड़ दिया जाने वाला भारी कारण आईडी संख्याओं के लिए है। यदि आपके पास नकारात्मक आईडी नंबर हैं, तो मुझे लगता है कि आपके पास बड़ी समस्याएं हैं ... क्या आप अपने पैड से '00000-1234' फॉर्म की उम्मीद कर रहे हैं? या '-000001234'? ईमानदारी से दिए गए सवाल का जवाब यह काम करता है, यह सरल है, यह साफ है, यह एक्स्टेंसिबल है। यह zfill नहीं हो सकता है, लेकिन यदि यह प्रश्न का उत्तर देता है तो इसे अपग्रेड किया जाना चाहिए।
TastySlowCooker
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.