separar por minusculas lower formato español declarar convertir concatenar caracter cadenas cadena python string

python - por - La mejor manera de rellenar ceros a una cadena



lower python español (13)

¿Cuál es la forma más pitón de rellenar una cadena numérica con ceros a la izquierda, es decir, para que la cadena numérica tenga una longitud específica?

str.zfill está específicamente destinado a hacer esto:

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

Tenga en cuenta que está diseñado específicamente para manejar cadenas numéricas según lo solicitado, y mueve un + o - al principio de la cadena:

>>> ''+1''.zfill(4) ''+001'' >>> ''-1''.zfill(4) ''-001''

Aquí está la ayuda en 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.

Actuación

Este es también el más alternativo de los métodos alternativos:

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

Para comparar mejor manzanas con manzanas para el método % (tenga en cuenta que en realidad es más lento), que de otro modo se calculará previamente:

>>> min(timeit.repeat(lambda: ''1''.zfill(0 or 4))) 0.19728074967861176 >>> min(timeit.repeat(lambda: ''%04d'' % (0 or 1))) 0.2347015216946602

Implementación

Con un poco de investigación, encontré la implementación del método zfill en 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; }

Vayamos a través de este código C.

Primero analiza el argumento de manera posicional, lo que significa que no permite argumentos de palabras clave:

>>> ''1''.zfill(width=4) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: zfill() takes no keyword arguments

Luego verifica si tiene la misma longitud o más, en cuyo caso devuelve la cadena.

>>> ''1''.zfill(0) ''1''

zfill calls pad (esta función de pad también se llama ljust , rjust , y center ). Básicamente, esto copia los contenidos en una nueva cadena y rellena el relleno.

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; }

Después de llamar al pad , zfill mueve cualquier + o - al principio de la cadena.

Tenga en cuenta que para que la cadena original sea realmente numérica no es necesario:

>>> ''+foo''.zfill(10) ''+000000foo'' >>> ''-foo''.zfill(10) ''-000000foo''

¿Cuál es la forma más pitónica de rellenar una cadena numérica con ceros a la izquierda, es decir, para que la cadena numérica tenga una longitud específica?


Comparación de tiempo rápida:

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]

He realizado diferentes pruebas de diferentes repeticiones. Las diferencias no son enormes, pero en todas las pruebas, la solución zfill fue la más rápida.


Funciona tanto en Python 2 como en Python 3:

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


Instrumentos de cuerda:

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

Y para los números:

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

Documentación de formato de cadena .


Para códigos postales guardados como enteros:

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


Para los números:

print "%05d" % number

Ver también: Python: Formato de cadena .

EDIT : vale la pena señalar que a partir del 3 de diciembre de 2008, este método de formato está obsoleto en favor del método de cadena de format :

print("{0:05d}".format(number)) # or print(format(number, "05d"))

Ver PEP 3101 para más detalles.


Para los que vinieron aquí para entender y no solo una respuesta rápida. Hago estos especialmente para cadenas de tiempo:

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" simboliza qué reemplazar con los caracteres de relleno "2", el valor predeterminado es un espacio vacío

Los símbolos ">" alinean todos los caracteres 2 "0" a la izquierda de la cadena

":" simboliza la format_spec


Solo usa el método rjust del objeto string.

Este ejemplo creará una cadena de 10 caracteres, rellenando según sea necesario.

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


También puede repetir "0", añadirlo previamente a str(n) y obtener el corte de ancho más a la derecha. Expresión rápida y sucia.

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


str(n).zfill(width) funcionará con la string s, int s, float s ... y es compatible con Python 2. xy 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''


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

Si quieres lo contrario:

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


>>> width = 4 >>> x = 5 >>> print("%0*d" %(width,x)) >>> 00005

esto funcionará en python 3.x


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

¡Vea la documentación impresa para todos los detalles emocionantes!

Actualización para Python 3.x (7.5 años después)

Esa última línea debería ser ahora:

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

Es decir, print() ahora es una función, no una declaración. Tenga en cuenta que todavía prefiero el estilo printf() Old School porque, IMNSHO, se lee mejor y porque, um, he estado usando esa notación desde enero de 1980. Algo ... perros viejos ... algo algo ... nuevos trucos.