The builtin center()
padding the extra character either on left or on the right depending on the string's length, e.g. 'bar'.center(10, '-')
is ---bar----
, the extra -
is on the right but hi.center(9,'-')
is ----hi---
, the extra is on the left.
But in my case I need the extra padding(if any) always on the left. What is the simple way to do that, as there are many ways to do that ?
And why does builtin center()
implement in this way? Actually I am more curious in this.
CodePudding user response:
The original implementation of str.center
was added here, in 1990:
# Center a string
def center(s, width):
n = len(s)
if n >= width: return s
return ' '*((width-n)/2) s ' '*(width -(width-n)/2)
It was changed a year later, in 1991, to
# Center a string
def center(s, width):
"""center(s, width) -> string
Return a center version of s, in a field of the specified
width. padded with spaces as needed. The string is never
truncated.
"""
n = width - len(s)
if n <= 0: return s
half = n/2
if n%2 and width%2:
# This ensures that center(center(s, i), j) = center(s, j)
half = half 1
return ' '*half s ' '*(n-half)
and the current C implementation found here does
static PyObject *
stringlib_center_impl(PyObject *self, Py_ssize_t width, char fillchar)
/*[clinic end generated code: output=d8da2e055288b4c2 input=3776fd278765d89b]*/
{
Py_ssize_t marg, left;
if (STRINGLIB_LEN(self) >= width) {
return return_self(self);
}
marg = width - STRINGLIB_LEN(self);
left = marg / 2 (marg & width & 1);
return pad(self, left, marg - left, fillchar);
}
I suspect the "why" for the current implementation is the
This ensures that center(center(s, i), j) = center(s, j)
comment, but you'd have to ask Guido for confirmation.
CodePudding user response:
You can implement your own version that left-pads the string.
It's pretty simple, you make sure center
creates an even-sized string, then if there is a reminder left you pad it on the left
In [1]: def left_center(word, sep, length):
...: reminder = (length - len(word)) % 2
...: return f'{reminder*sep}{word.center(length-reminder, sep)}'
...:
In [2]: left_center('bar', '-', 10)
Out[2]: '----bar---'
In [3]: left_center('hi', '-', 9)
Out[3]: '----hi---'
for left_center('bar', '-', 10)
it does this:
reminder = (10 - 3) % 2 # which is equal to 1
f'{1*"-"}{"bar".center(9, "-")} # '----bar---'