format string to certain line width

E

elukkien

Hello!

I'm trying to find a way to print out a long string (>400 characters no
spaces, tabs or newlines) to a line width of 60 characters. So after every
60 characters a newline would start. Is it possible to transform the
string to set the linewidth?

for example for a linewidth of 2:

.... {do something to str to set width to 2} ...
He
LL
oW
or
ld
!

i know in Perl this works:
my $str = "HelloWorld!" ;
$str =~ s/.{2}/$&\n/g ; #at {2} you can then specify the desired width
print $ str ;

But how to do it in Python?
An option in the print statement would also be fine.
Something like: print "%{2}s" %(str)

Of course i could do it in a for loop and print 60 characters, print a \n,
print the next 60 characters, print a \n ...
But i imagine there will be a more efficient way.

Thanks
Eddie
 
E

elukkien

import textwrap
He
ll
oW
or
ld

Of course if your assertion that the string contains no spaces, tabs or
newlines turns out to be incorrect this may not do what you wanted.

Thanks, i just found this myself and it works fine, but very slow...
The script without the wrapping takes 30 seconds, with wrapping 30
minutes. Is there not a more efficient way?
The perl syntax i posted is much faster.
 
F

Fredrik Lundh

Thanks, i just found this myself and it works fine, but very slow...
The script without the wrapping takes 30 seconds, with wrapping 30
minutes. Is there not a more efficient way?

sounds like you're wrapping a few million long strings, not just one...

here are two approaches that are about 10x faster than textwrap:

re.findall('..', my_string)

or

[my_string[i:i+2] for i in xrange(0, len(my_string), 2]

the above gives you lists of string fragments; you can either join them
before printing; e.g.

print "'\n'.join(re.findall('..', my_string))

or use writelines directly:

sys.stdout.writelines(s + "\n" for s in re.findall('..', my_string))

Python's re.sub isn't as efficient as Perl's corresponding function, so
a direct translation of your Perl code to

re.sub('(..)', r'\1\n', my_string)

or, faster (!):

re.sub('(..)', lambda m: m.group() + "\n", my_string)

is not as fast as the above solutions.

</F>
 
J

John Machin

Thanks, i just found this myself and it works fine, but very slow...
The script without the wrapping takes 30 seconds, with wrapping 30
minutes. Is there not a more efficient way?
The perl syntax i posted is much faster.
.... return ''.join(s[x:x+w] + '\n' for x in xrange(0, len(s), w))
....
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,607
Members
45,240
Latest member
pashute

Latest Threads

Top