2008-11-30 14 views
6

¿Hay alguna lib que convierta números muy largos en cadenas simplemente copiando los datos?long <-> str conversión binaria

Estos chistes son demasiado lentos:

def xlong(s): 
    return sum([ord(c) << e*8 for e,c in enumerate(s)]) 

def xstr(x): 
    return chr(x&255) + xstr(x >> 8) if x else '' 

print xlong('abcd'*1024) % 666 
print xstr(13**666) 

Respuesta

4

desea que el módulo de estructura.

packed = struct.pack('l', 123456) 
assert struct.unpack('l', packed)[0] == 123456 
+0

No funcionará para números grandes, por ejemplo, 13 ** 666 – jfs

2

¿Qué tal

from binascii import hexlify, unhexlify 

def xstr(x): 
    hex = '%x' % x 
    return unhexlify('0'*(len(hex)%2) + hex)[::-1] 

def xlong(s): 
    return int(hexlify(s[::-1]), 16) 

no tenía tiempo que pero debería ser más rápido y también trabajar en números más grandes, ya que no utiliza la recursividad.

0

Supongo que no te importa el formato de cadena, ¿solo quieres una serialización? Si es así, ¿por qué no utilizar el serializador integrado de Python, el módulo cPickle? La función dumps convertirá cualquier objeto de python, incluido un entero largo en una cadena, y la función loads es su inversa. Si está haciendo esto para guardar en un archivo, revise las funciones dump y load, también.

>>> import cPickle 
>>> print cPickle.loads(cPickle.dumps(13**666)) % 666 
73 
>>> print (13**666) % 666 
73 
1

Si usted necesita el uso de serialización rápida marshal módulo. Es alrededor de 400 veces más rápido que tus métodos.

-1

Rendimiento de cPickle vs marshal (Python 2.5.2, Windows):

python -mtimeit -s"from cPickle import loads,dumps;d=13**666" "loads(dumps(d))" 
1000 loops, best of 3: 600 usec per loop 

python -mtimeit -s"from marshal import loads,dumps;d=13**666" "loads(dumps(d))" 
100000 loops, best of 3: 7.79 usec per loop 

python -mtimeit -s"from pickle import loads,dumps;d= 13**666" "loads(dumps(d))" 
1000 loops, best of 3: 644 usec per loop 

marshal es mucho más rápido.

+6

Solo si lo usa ingenuamente. pickle se establece de manera predeterminada en un protocolo textual compatible con versiones anteriores. Use cPickle.dumps (d, -1) y los tiempos sean competitivos: en mi máquina, 4.63 usec/loop para cPickle vs 3.34 usec/loop para Marshal. –

2

De hecho, tengo una falta de long (s, 256). Yo se esconden más y veo que hay 2 función en Python CAPI archivo "longobject.h":

PyObject * _PyLong_FromByteArray(const unsigned char* bytes, size_t n, int little_endian, int is_signed); 
int _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed); 

Ellos hacen el trabajo. No sé por qué no están incluidos en algún módulo de Python, o corríjanme si me equivoco.

+1

En Python3 hay métodos 'int.from_bytes' /' int.to_bytes'. http://docs.python.org/dev/py3k/library/stdtypes.html?highlight=int.from_bytes#int.to_bytes – jfs

Cuestiones relacionadas