Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Digit grouping in python hexadecimal number formatting

Say I have a bunch of hexadecimal numbers that I’m printing in python, e,g, addresses for debugging purposes, and I want to be able to compare them visually. A great help for that would be to group digits similarly to how we use thousands separators for decimal numbers.

This is also the reason why when you hexdump something digits are grouped by 4, rather than unfathomly long strings of hexadecimal characters.

Unreadable: 47167689711616
Barely readable: 2ae61563e000
Half-readable: 47,167,689,711,616
Most-readable: 2ae6,1563,e000

I don't really care what the separator is, if the grouping is by 2, 3, or 4 digits. However, the option for grouping seems not to be working:

>>> '{:x}'.format(47167689711616)
'2ae61563e000'
>>> '{:,x}'.format(47167689711616)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Cannot specify ',' with 'x'.

The machine I’m using (and where I’m not admin) only has python 3.4.

like image 846
Cimbali Avatar asked Jul 02 '26 10:07

Cimbali


2 Answers

A new grouping option “_” has been introduced in python 3.6:

The '_' option signals the use of an underscore for a thousands separator for floating point presentation types and for integer presentation type 'd'. For integer presentation types 'b', 'o', 'x', and 'X', underscores will be inserted every 4 digits. For other presentation types, specifying this option is an error.

Changed in version 3.6: Added the '_' option (see also PEP 515 -- Underscores in Numeric Literals).

Example:

>>> '{:_x}'.format(47167689711616)
'2ae6_1563_e000'

Of course this helps on an up-to-date machine, but not with python 3.4.

like image 176
Cimbali Avatar answered Jul 05 '26 18:07

Cimbali


You can achieve this using the grouper recipe from the itertools docs.

>>> import itertools

>>> def grouper(iterable, n, fillvalue=None):
...     args = [iter(iterable)] * n
...     return itertools.zip_longest(*args, fillvalue=fillvalue)
... 
>>>

>>> n = 47167689711616
>>> fs = '{:x}'.format(n) 
>>> fs
'2ae61563e000'
>>> list(''.join(x) for x in grouper(fs, 4, '0'))
['2ae6', '1563', 'e000']

Or for string ooutput:

>>> ' '.join(''.join(x) for x in grouper(fs, 4, '0'))
'2ae6 1563 e000'

This will work on Python 3.4

like image 29
snakecharmerb Avatar answered Jul 05 '26 17:07

snakecharmerb