sambasam
sambasam

Reputation: 47

Python - specifying lengths of strings, mostly

I have a program that returns a number (6, at the moment) of numerical results, converts them to strings, then concatenates them for sending over ZMQ.

Example outputs are:

Results: 7.85, -5.75, 16.0, 0.0, 0.84375, 0.828125

7.85-5.7516.00.00.843750.828125

Results: 5.25, -10.72, 8.5, 0.0, 0.752, 0.8265

5.25-10.728.50.00.7520.8265

After receiving this string through ZMQ I then need to split it apart again.

To make this work, I think specifying the length of the strings is the simplest way to go, so I always know I'll have x characters for each answer, and I can then use stringsplit at the end to get my individual results.

Problem is I can't find out how to do that. I know how to specify the number of decimal places, but when I have single/double digit whole numbers, sometimes with - signs, I get a bit stuck...

thanks

Upvotes: 1

Views: 170

Answers (2)

wobmene
wobmene

Reputation: 1138

I see you are using ZMQ and that's why I suppose you want better performance. If so try to use cPickle module (it is available in standard Python library) for packing this list instead of converting it to string.

Here is a code for comparing efficiency of both ways:

import time
import cPickle
import random

random.seed()
l = [ random.random()*1000 for i in xrange(100000) ]

t0 = time.time()
s1 = ','.join(map(str,l))
t1 = time.time() - t0

t0 = time.time()
s2 = cPickle.dumps(l, -1)
t2 = time.time() - t0

print 's1: len1=%s t1=%s' % (len(s1), t1)
print 's2: len2=%s t2=%s' % (len(s2), t2)
print 's2/s1: len2/len1=%s t2/t1=%s' % (float(len(s2))/len(s1), t2/t1)

and it's output:

s1: len1=1389129 t1=0.281008005142
s2: len2=900206 t2=0.0193469524384
s2/s1: len2/len1=0.648036287487 t2/t1=0.0688484031925

you can see that cPickle way is much faster (x14.5 times faster) and efficient in terms of size of data you have to transmit (64%).

For getting the list from pickled object you should use

l = cPickle.loads(s2)

Hope it helps.

Upvotes: 2

Chris Taylor
Chris Taylor

Reputation: 47392

Here's some code demonstrating the approach that I recommended in my comment.

This is the list of results from your program (if they don't come in a list already, put them into one):

>>> nums = [1,2,3,4,5,6]

Now we use map(str,nums) to convert each of the numbers to a string, and join them together with commas between them by calling the .join() method of the string literal ',':

>>> mystr = ','.join(map(str,nums))
>>> mystr
'1,2,3,4,5,6'

The call map(str,nums) means "Apply the function str (which converts things to a string) to every element of the array nums and store the results in an array." The map is a powerful functional programming idiom that you can use to considerably shorten your code (see Wikipedia).

Finally, you use the split method on your string to pull it apart whenever a comma appears, and use map(float,-) to convert the strings back into floating point numbers:

>>> map(float,mystr.split(','))
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]

Upvotes: 6

Related Questions