Color a list or a string

Hi everyone,

Is there a way to color a string or a list/tuple ? for example something that we can do is the following:

H = 'hello'
res = ''
for i in range(len(H)):
     res += f'\033[0;33m{H[i]}'
print(res)

This will print the word hello in yellow. However if we try to return it as a string then it fails:

H = 'hello'
res = ''
for i in range(len(H)):
     res += f'\033[0;33m{H[i]}'
return res

I also have no idea how to convert a list in black into the same list but in red say. I’m not even sure that it makes sens to do it but it would be pretty convenient.

Thank you for your help,
Cheers,
Nathan

I don’t really understand what you’re trying to do. return only makes sense in a function and you don’t have one.

Hi ND,

I meant res instead of return res.

Thanks,
Nathan

There’s a library for this kind of formatting.

A quick demo:

from termcolor import colored

print("This is the default text color in terminal")
print()
print(colored("This is a red text in terminal", "red"))
print()
print(colored("This is a green text in terminal", "green"))
print()
print(colored("This is a red text with a green background", "red", "on_green"))
print()

word_list = ['Hello', 'world']

for word in word_list:
    print(colored(word, "yellow"), end=' ')
print()

Or (better still) python3 -m termcolor

Hi Rob,

Thanks for the answer, but what I’m looking for is a way to have a string in color, not to print a string and get it with the color.

It’s a little bit strange but I really need the object to be either a string or a list but with the particularity of being in a specific color.

Cheers,
Nathan

You’re welcome.

The only other item I have in my notes on this topic is:

Rich’s documentation


… but I’ve not tried that package and don’t know if it’s what you’re looking for.

Have a good day.

[edit done to clean up the post]

It’s important to understand here that the colouring done here is completely out of Python’s hands. When you run the Python interpreter in a terminal window, the terminal itself is a separate program, and that is the program that is actually interpreting these special characters as commands to change the colour.

The codes for specific colours are part of a standard called ANSI. You can research this easily with a search engine, but adding these special colour-formatting sequences to strings is tedious and error-prone. It’s better to use a third-party library for this task. @rob42 already showed you termcolor. Another library worth mentioning is colorama; it doesn’t solve quite the same problems, though.

In an interpreter session, writing something like res will cause the interpreter to echo back a string representation of whatever object res is, using the built-in repr to create that representation. This version will put quotes around strings and use escape sequences for special characters, because its purpose is to show you what an object actually is, not to display text. Using str will not help, because the interpreter will still take the repr of that str. (In fact, using str here will do nothing, because res is already a string.)

This cannot really be done, because the colour is not a property of the string, list, or any other Python object. It is a result of work done by another program, when you give it special text. However, with a bit of work, you can make objects that are naturally displayed in a specific color. If your terminal supports ANSI.

You cannot change the text that will be used to represent a built-in string or list with repr. However, you can create your own classes, and use the special __repr__ method to describe what will happen when repr is used on the object. You can also inherit from the built-in str and list types. Thus, taking advantage of termcolor:

>>> from termcolor import colored
>>> class RedList(list):
...     def __repr__(self):
...         return colored(super().__repr__(), 'red')
... 
>>> RedList([1,2,3])
[1, 2, 3]
>>>

It isn’t shown here, but the RedList instance should show up in red in the terminal.

Similarly,

>>> class GreenString(str):
...     def __repr__(self):
...         return colored(super().__repr__(), 'green')
... 
>>> GreenString('test')
'test'

The string will show up in green - including the quotes, because they are part of the text that colored is surrounding with ANSI color codes.

3 Likes

What do you mean “have a string in color, not print it with the color”?

Do you mean you want to have a string type with an additional property that is its colour, or something else?

Hi Karl and thanks for the explanations. Very precise :slightly_smiling_face:.

And ND, to explain a little bit why I want, I’m trying to construct a poset P (that is a partial ordered set) in SageMath (basically this is Python with a big mathematical library) and a particularity of the object P is that it eats tuples, strings or lists. Until here everything is fine, but now I also need to emphasize some elements in P, and the way I want to do it is by coloring some of them. Since the elements of the poset are either, list, strings, tuples, I must keep the same “nature” when coloring…
But it seems that it is not really possible after what Karl wrote :frowning:

Assuming that the poset is represented by your own class, you could implement __repr__ for that class. But we’d have to see more details to advise any further.

Lots of things are possible. It does sound to me like you want additional properties on those objects, rather than having colours for output.

Perhaps something like this:

from dataclasses import dataclass
from enum import Enum


Colour = Enum("Colour", ["RED", "GREEN", "BLUE"])


@dataclass
class ColouredObject:
    value: object
    colour: Colour


a_string = ColouredObject("foo", Colour.BLUE)

a_list = ColouredObject([1, 2, 3], Colour.RED)

some_objects = [a_string, a_list]

for an_object in some_objects:
    if isinstance(an_object.value, str):
        print(f"String: {an_object.value} with colour: {an_object.colour}")
    else:
        print("Not a string!")

I’ve got an old version of Python on this machine; in a newer one I’d use the pattern matching instead of isinstance.

Does this help any?

Thanks to everyone for all the answers, I will test them later on and will let you know what worked :wink:

Cheers,
Nathan