Hypothetical Ninja
Hypothetical Ninja

Reputation: 4077

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?

Upvotes: 0

Views: 390

Answers (1)

Carsten
Carsten

Reputation: 18446

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.

Upvotes: 4

Related Questions