OneWorld
OneWorld

Reputation: 163

list comprehension or shorter form that achieves rgb to hex for colour palette

How could i convert this for loop into a list comprehension ?

rgb_arr = [[217, 180, 131], [242, 228, 221], [132, 174, 221], [203, 135, 74], [28, 49, 21],
[154, 179, 101], [213, 200, 186], [87, 143, 51]]

hex_palette = []
for rgb in rgb_arr:
    col_hex = '#' + hex(rgb[0]).split('x')[-1] + hex(rgb[1]).split('x')[-1] + hex(rgb[2]).split('x')[-1]
    hex_palette.append(col_hex)
print(hex_palette)

The resulting hex list from the print statement should look like this

['#d9b483', '#f2e4dd', '#84aedd', '#cb874a', '#1c3115', '#9ab365', '#d5c8ba', '#578f33']

Is there a pythonic way of reducing the repetition of this part ?:-

hex(rgb[0]).split('x')[-1] +

Upvotes: 1

Views: 233

Answers (6)

blhsing
blhsing

Reputation: 107134

If the goal is to minimize code repetition, you can also map the color values to the format method of the formatting string:

[f"#{''.join(map('{:02x}'.format, c))}" for c in rgb_arr]

Upvotes: 1

Pedro Lobito
Pedro Lobito

Reputation: 99081

The lazy way using webcolors:

from webcolors import rgb_to_hex
rgb_arr = [[217, 180, 131], [242, 228, 221], [132, 174, 221], [203, 135, 74], [28, 49, 21], [154, 179, 101], [213, 200, 186], [87, 143, 51]]
[rgb_to_hex(x) for x in rgb_arr]

pip install webcolors

Upvotes: 0

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 96360

The most straightforward way to do this is to use string formatting, in a list copmrehension or not:

[f'#{a:02x}{b:02x}{c:02x}' for a,b,c in rgb_arr]

Or just:

result = []
for a,b,c in rgb_arr:
    result.append(f'#{a:02x}{b:02x}{c:02x}')

Upvotes: 2

Derek Eden
Derek Eden

Reputation: 4638

could also use matplotlib built in functions...

from matplotlib.colors import to_hex

you can either normalize your RGB ints before hand or just convert it to a numpy array and do this:

rgb_arr = np.array(rgb_arr)
hex_palette = [to_hex(rgb/255) for rgb in rgb_arr]

output:

['#d9b483', '#f2e4dd', '#84aedd', '#cb874a', '#1c3115', '#9ab365', '#d5c8ba', '#578f33']

Upvotes: 1

Scott Hunter
Scott Hunter

Reputation: 49920

One more variation:

[("#%02x%02x%02x"%tuple(b)) for b in rgb_arr]

(to take care of values < 10).

Upvotes: 1

You can simply use list comprehension and f-strings:

hex_palette = [f"#{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}" for rgb in rgb_arr]

On the formatting the initial 0 means to fill up the empty spaces with 0-s, the 2 means fill up until two characters and the x means use hexadecimal.

Or, if you are using an older Python like 3.5, you can use string formatting instead of f-strings:

hex_palette = ["#{rgb[0]:02x}{rgb[1]:02x}{rgb[2]:02x}".format(rgb=rgb) for rgb in rgb_arr]

Upvotes: 1

Related Questions