Hypothetical Ninja Hypothetical Ninja - 1 year ago 57
Python Question

Create a list of hex codes given an Rgb range

I have these 3 vertices (end values) of

RGB
as
#ff0000
,
#ffcfcf
and
#350000
where
R
varies from
35
to
ff
,
G
from
00
to
cf
and
B
from
00
to
cf
. I need to create a list of all the possible values between them. I did the following:

import re
my_list=[]
for i in xrange(53,256):
for j in xrange(0,208):
for k in xrange(0,208):
item = str(hex(i))+str(hex(j))+str(hex(k))
item2 = re.sub('(0x)','',item)
my_list.append(item2)


I iterated over the integer values and converted them to hex, followed by concatenating
RGB
values and replacing
0x
from the concatenated string(which doesn't work) . This method is quite slow. Is there a better way to do this?

Answer Source

As a benchmark, I ran your code on my computer. It needed 27.8 s.

Regular expressions are always costly, so let's replace them by simple string replacement:

my_list=[]
for i in xrange(53,256):
    for j in xrange(0,208):
        for k in xrange(0,208):
            item = str(hex(i))+str(hex(j))+str(hex(k))
            item2 = item.replace("0x", "")
            my_list.append(item2)

This takes 8.8 s.

But all this taking string representations of hexadecimal numbers and removing the 0x in front of it seems a bit off to me, especially since Python has built-in string formatting for that purpose:

my_list=[]
for i in xrange(53,256):
    for j in xrange(0,208):
        for k in xrange(0,208):
            my_list.append("{0:02x}{1:02x}{2:02x}".format(i,j,k))

This takes 8.3 s. A tiny bit better, but it also looks a bit cleaner. If we use itertools, we can even write this as a one-liner (sans long line break and import statement):

import itertools
my_list = ["{0:02x}{1:02x}{2:02x}".format(i,j,k) for i,j,k
           in itertools.product(xrange(53,256), xrange(0,208), xrange(0,208))]

This takes 8.1 s. Still not there.

Right now, the string formatting is the operation which costs most time. It is also an operation that we can avoid easily (since we're only ever formatting the same 256 values). Let's create a lookup table:

import itertools
m = ["{0:02x}".format(i) for i in xrange(256)]
my_list = [m[i] + m[j] + m[k] for i,j,k
        in itertools.product(xrange(53,256), xrange(0,208), xrange(0,208))]

Run time: 1.6 s. Hopefully fast enough.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download