HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Efficiently creating a list of formatted hex values

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
efficientlycreatingformattedhexvalueslist

Problem

My background is in C, and I'm finally learning this new-fangled "Python" that all the cool kids are talking about.

I want to create a list of formatted hexadecimal values like so:

['0x00','0x01','0x02','0x03' (...) '0xfe','0xff']


Please note that the leading zero's shouldn't be stripped. For example, I want 0x03, not 0x3.

My first successful attempt was this:

hexlist=list()
tempbytes = bytes(range(256))
for value in tempbytes:
    hexlist.append("0x" + tempbytes[value:value+1].hex())
del tempbytes


But, wow this is ugly. Then I tried to make it more Pythonic ("Pythony"?) like so:

hexlist = ["0x"+bytes(range(256))[x:x+1].hex() for x in bytes(range(256))]


My thoughts:

  • OMG! That's harder to read, not easier!



  • Not only that, but I had to invoke range twice, which I assume is inefficient.



  • I bet there's a much better way that I haven't been exposed to yet...



My questions:

  • Is the second much less efficient?



  • Is there a better way to do this?



  • What's the best thing to do here in keeping with python style?

Solution

The shortest and most readable way to do it would probably be

hexlist = [hex(x) for x in range(256)]


Time

Your first : 0.1 ms per loop for \$10^5\$ loops

Your second: 1 ms per loop for \$10^5\$ loops

The above : 0.02 ms per loop for \$10^5\$ loops

I'm unable to com up with a worse example, but there is always a worse way to do it, exactly as there is always preferable way to do it.

Edit
To do this with filled zeros I would suggest to treat the first 10 numbers as a special case.

hexlist = [hex(x) if x > 15 else "{:#04x}".format(x) for x in range(256)]


new time: 0.04 ms. Even if it isn't as pretty.

Edit:

And when considering that format can format binary numbers, why not hex?

hexlist = ["{:#04x}".format(x) for x in range(256)]


I guess that this is hard coded for this range, but anyway.

Time: 0.1ms for per loop for \$10^5\$ loops.

And more edits

Using old style:.

hexlist = ["0x%02x" % n for n in range(256)]


Time: 0.08ms per loop for \$10^5\$ loops.

And specifically generating what we want.

hexlist = ["{:#04x}".format(x) for x in range(16)] + \
              [hex(x) for x in range(16, 256)]


Time: 0.03ms per loop for \$10^5\$ loops.

Code Snippets

hexlist = [hex(x) for x in range(256)]
hexlist = [hex(x) if x > 15 else "{:#04x}".format(x) for x in range(256)]
hexlist = ["{:#04x}".format(x) for x in range(256)]
hexlist = ["0x%02x" % n for n in range(256)]
hexlist = ["{:#04x}".format(x) for x in range(16)] + \
              [hex(x) for x in range(16, 256)]

Context

StackExchange Code Review Q#147160, answer score: 4

Revisions (0)

No revisions yet.