La funzione struct.pack() consente di convertire interi di stringhe fino a 64 bit in byte. Qual è il modo più efficiente per comprimere un intero ancora più grande? Preferirei non aggiungere una dipendenza a moduli non standard come PyCrypto (che fornisce num_to_bytes()).Imballaggio intero efficiente di dimensioni arbitrarie in Python
risposta
Come suggerito da S.Lott in un commento, è sufficiente convertire il numero in una stringa e comprimere tale stringa. Ad esempio,
x = 2 ** 12345
struct.pack("40s", str(x))
Ciò è ancora meno efficiente della semplice memorizzazione della rappresentazione di stringa dell'intero, a causa del riempimento dell'int con byte null. –
La domanda non è chiara quale tipo di efficienza è richiesta? Stiamo cercando l'uso più efficiente dello spazio? O forse il minimo tempo di elaborazione per impacchettare la struttura? Del resto, l'efficienza è anche un grosso problema? La domanda ha richiesto la risposta più efficace, ma le persone spesso si ottimizzano prematuramente. –
Assumendo il manifesto vuole confezionare un intero grande come una stringa binaria, cioè non utilizzare un byte di archiviazione per cifra del numero. Un modo di fare questo sembra essere:
import marshal
a = 47L
print marshal.dumps(a)
Questo stampa:
'l\x01\x00\x00\x00/\x00'
Non posso dire che ho capito come interpretare questi bit, in questo momento ...
Sta andando nella giusta direzione, ma ha ancora due byte ridondanti nella parte anteriore. –
@Mike: In realtà più di questo - penso che la "l" e le prime 4 cifre siano solo un conteggio del contenuto, seguito da un singolo byte ("/" == chr (47)) e da un nullo alla fine. Sembra che il maresciallo stia facendo uno schema di codifica più complesso includendo solo i byte grezzi (guarda i dump (2 ** 64-1) per esempio e non i byte 0x7f nel mezzo. – Brian
I intendi vuoi dire che vuoi solo usare tanti byte quanti ne hai bisogno per rappresentare il numero? per esempio. se il numero è:
- 255 o meno devi usare solo 1 byte
- 65535 o meno 2 byte
- 16777215 o inferiore a 3 byte
- etc etc
Sul Di solito il PDA di Psion ha uno schema di compressione in cui si legge il primo byte, si rileva se ha il bit più alto impostato e quindi legge un altro byte se lo ha. In questo modo continui a leggere i byte finché non leggi il numero "completo". Questo sistema funziona piuttosto bene se la maggior parte dei numeri con cui si ha a che fare sono abbastanza piccoli, poiché normalmente utilizzerai solo uno o due byte per numero.
L'alternativa è di avere uno (o più) byte che rappresentano il numero di byte totali utilizzati, ma a quel punto è fondamentalmente una stringa in Python comunque. vale a dire una stringa di 256 cifre base.
vuoi dire qualcosa come questo:
def num_to_bytes(num):
bytes = []
num = abs(num) # Because I am unsure about negatives...
while num > 0:
bytes.append(chr(num % 256))
num >>= 8
return ''.join(reversed(bytes))
def bytes_to_num(bytes):
num = 0
for byte in bytes:
num <<= 8
num += ord(byte)
return num
for n in (1, 16, 256, 257, 1234567890987654321):
print n,
print num_to_bytes(n).encode('hex'),
print bytes_to_num(num_to_bytes(n))
che restituisce:
1 01 1
16 10 16
256 0100 256
257 0101 257
1234567890987654321 112210f4b16c1cb1 1234567890987654321
io non sono solo sicuro di cosa fare al riguardo negativi ... io non sono così familiare con un po 'di rumore.
EDIT: Un'altra soluzione (che gestisce circa il 30% più veloce con i miei test):
def num_to_bytes(num):
num = hex(num)[2:].rstrip('L')
if len(num) % 2:
return ('0%s' % num).decode('hex')
return num.decode('hex')
def bytes_to_num(bytes):
return int(bytes.encode('hex'), 16)
Sì, questo è ciò che intendo, e Ho scritto una funzione simile qualche tempo fa, ma volevo qualcosa che fosse più facile da "port", come un trucco di comprensione delle liste o (meglio) una funzione di libreria che non conoscevo. – noamtm
Ho appena pubblicato un altro transcodifica int/hex e hex/str transconding ... Anche questo è un po 'più veloce! –
@noamtm: Si prega di aggiornare la domanda con fatti aggiuntivi. Non nascondere solo le informazioni nei commenti. –
Questo è un po 'hacky, ma si potrebbe passare attraverso la rappresentazione di stringa esadecimale, e lì per binari con il codec hex:
>>> a = 2**60
>>> a
1152921504606846976L
>>> hex(a)
'0x1000000000000000L'
>>> hex(a).rstrip("L")[2:].decode('hex')
'\x10\x00\x00\x00\x00\x00\x00\x00' # 8bytes, as expected.
>>> int(_.encode('hex'), 16)
1152921504606846976L
si rompe un po 'perché il codec esagonale richiede un numero pari di cifre, quindi avrai bisogno di pad per questo, e avrete bisogno di impostare un flag per gestire i numeri negativi.Ecco un generico pacchetto/decompressione:
def pack(num):
if num <0:
num = (abs(num) << 1) | 1 # Hack - encode sign as lowest bit.
else:
num = num << 1
hexval = hex(num).rstrip("L")[2:]
if len(hexval)%2 ==1: hexval = '0' + hexval
return hexval.decode('hex')
def unpack(s):
val = int(s.encode('hex'), 16)
sign = -1 if (val & 1) else 1
return sign * (val>>1)
for i in [10,4534,23467, 93485093485, 2**50, 2**60-1, -1, -20, -2**60]:
assert unpack(pack(i)) == i
Con tutto il giocherellare per etc imbottitura richiesta, io non sono sicuro che è molto meglio di una soluzione arrotolato a mano però.
- 1. Algoritmo di imballaggio efficiente per poligoni regolari
- 2. Python Implementazioni di imballaggio Algoritmo
- 3. Iterate attraverso una serie di dimensioni arbitrarie
- 4. Dati MySQL di gruppo in intervalli temporali di dimensioni arbitrarie
- 5. Ottimale 4 Parola posizionamento all'interno di dimensioni arbitrarie Griglia
- 6. moltiplicazione di array numpy con matrici di dimensioni arbitrarie
- 7. Elaborazione di un file .txt di grandi dimensioni in python in modo efficiente
- 8. Imballaggio massimo di rettangoli in un cerchio
- 9. Come caricare file di piccole dimensioni in Amazon S3 in modo efficiente in Python
- 10. modo Efficiente di dividere un file di testo di grandi dimensioni in python
- 11. Maschera dimensioni arbitrarie UIImageView con UIImage ridimensionabile maschera
- 12. UIWebview a schermo intero dimensioni
- 13. Leggere in modo efficiente file di testo di grandi dimensioni
- 14. Librerie di precisione arbitrarie JVM
- 15. Esiste una memoria efficiente e veloce per caricare file json di grandi dimensioni in python?
- 16. Enumerazione efficiente di sottoinsiemi ordinati in Python
- 17. Paging efficiente con tabelle di grandi dimensioni in sql 2008
- 18. Come dividere in modo efficiente file di grandi dimensioni
- 19. Imballaggio di bit di array di numeri interi
- 20. Algoritmo di imballaggio bin 3D
- 21. Derivazione di funzioni arbitrarie in Haskell
- 22. Cancella intero array Python
- 23. Python regex per intero?
- 24. Python SHA1 Numero intero
- 25. Python: dimensioni di stringhe in memoria
- 26. Pdf RDF di grandi dimensioni in Python
- 27. Python intero incrementando con ++
- 28. Struttura dati per archiviare tabelle di database arbitrarie
- 29. python argparse per gestire opzioni numeriche arbitrarie (come HEAD (1))
- 30. riduzione efficiente dei molteplici tensori in Python
Non so di cosa stai parlando. Vuoi mettere la versione stringa di un Python lungo in una struct? La versione stringa di long è una stringa; lo impacchetta come qualsiasi altra stringa. Qual è la tua vera domanda? –
L'OP desidera impacchettare, nel modo più efficiente possibile, un numero intero di dimensioni arbitrarie in una rappresentazione di stringa di byte ragionevole. –