November 04, 2003
Right Padding A String
I've been writing some Java today, shock horror. I approached it as if I was writing some Python code, but just with more symbols in the source code.
It was a nice reminder that even in such similar languages, common idioms don't necessarily travel. As an example I wanted to right pad a string. This isn't supported by the String class, so I wrote a method;
public String rightPad(String s, int length, char pad) { StringBuffer buffer = new StringBuffer(s); int curLen=s.length(); if (curLen < length) { for (int i=0; i<length; i++) { buffer.append(pad); } } return buffer.toString(); }
Then I tried to implement it in Python. Here is my first pass;
def fill(fillString, toLength, fillChar): while len(fillString) < toLength: fillString += fillChar return fillString
Which is pretty much a direct copy of the Java code. But, I thought, there must be a more Pythonic way, so I came up with;
def newFill(fillString, toLength, fillChar): return fillString+''.join([fillChar for x in range(len(fillString),toLength)])
Hmmm, I'm not sure if its better, or just more obscure. It looks awfully LISP like to me.
Posted by Andy Todd at November 04, 2003 08:28 PM
fillLength = toLength - len(fillString)
return fillString + fillChar*fillLength
Python 2.3.1 (#1, Sep 24 2003, 16:45:45)
[GCC 3.2.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from timeit import Timer
>>> def fillLength(s, l, c):
... return ''.join([s,] + [c,] * (l - len(s)))
...
>>> t = Timer(stmt="fillLength('pippo', 7, ' ')", setup="def fillLength(s, l, c):\n return ''.join([s,] + [c,] * (l - len(s)))") >>>
>>> t.timeit()
9.507375955581665
>>> t2 = Timer(stmt="newFill('pippo', 7, ' ')", setup="def newFill(fillString, toLength, fillChar):\n return fillString+''.join([fillChar for x in range(len(fillString),toLength)])")
>>> t2.timeit()
11.33608603477478
>>>
forgot the fastest
>>> t = Timer(stmt="fillString('pippo', 7, ' ')", setup="def fillString(s, l, c):\n return s + c * (l - len(s))")
3.0397789478302002
>>>
And as for Java, don't reinvent the wheel:
http://jakarta.apache.org/commons/lang/api/org/apache/commons/lang/StringUtils.html#rightPad(java.lang.String,%20int,%20char)
Posted by: Simon Brunning on November 5, 2003 09:10 AMHmmm. Buggered *that* UR%L up, didn't I. Any road up, I'm sure you can find it - the Jakarta Commons Lang package.
Posted by: Simon Brunning on November 5, 2003 09:21 AMAh yes Simon, but that's Open Source and our Java visionaries here at work don't hold with any of that kind of rubbish
Posted by: Andy Todd on November 5, 2003 05:34 PMYeah - bunch of commie pinkos, the open source crowd. ;-)
Posted by: Simon Brunning on November 6, 2003 01:15 PMYou can shorten the Java one to this:
public String rightPad(String s, int length, char pad)
{
if (s.length() >= length) return s;
StringBuffer buffer = new StringBuffer(s);
for (int i = length - s.length(); i > 0; --i) buffer.append(pad);
return buffer.toString();
}
It looks like your Java rightPad method doesn't actually work correctly. Why are you going from i = 0 to i = length?
Posted by: Titus Barik on May 17, 2005 07:28 AM