3

I'm trying to print a file in rainbow colors. But however I have a problem, here is my code:

color = [91, 93, 92, 96, 94, 95]

with open(sys.argv[1]) as f:
for i in f.read():
    for c in color:
        print('\033[{0}m{1}\033[{0};m'
              .format(c, i), end='', flush=True)

The question is, I want the output like this: Hello(H in red, e in yellow, etc. ), but I got the output like this:HHHHHeeeeellll...(first H in red, second H in yello, etc.).

I know that because the first for will loop the second for. But how can I solve this?

3 Answers 3

2

You don't want to loop over the colours for each letter just cycle through the colours, you can use itertools.cycle to cycle through the colors just calling next() to get the next color:

from itertools import cycle
color = cycle([91, 93, 92, 96, 94, 95])

with open(sys.argv[1]) as f:
    for i in f.read():
       print('\033[{0}m{1}\033[{0};m'
             .format(next(color), i), end='', flush=True)
Sign up to request clarification or add additional context in comments.

2 Comments

It turns [1,2,3] into the infinite list [1,2,3,1,2,3,1,2,3,...] but without the overhead of creating the list (see generators)
I understand, it will create a generator, and that turns [1,2,3] into [1,2,3,1,2,3,1,2,3,...] . Then we use next() to call it. right?
1

You have to iterate them in a "zipping" way, possibly repeating the second one.

color = [91, 93, 92, 96, 94, 95]

with open(sys.argv[1]) as f:
    for i, c in itertools.izip(f.read(), itertools.cycle(color)):
        print('\033[{0}m{1}\033[{0};m'
          .format(c, i), end='', flush=True)

7 Comments

hum, I got this error: AttributeError: 'module' object has no attribute 'izip'
In python 3 you don't need itertools.izip just zip will do.
It's working! and what's the difference between your answer and @achampion 's answer?
Not much, both use cycle to create an infinite list of cycling colors, but this uses zip() to join the letter and color, vs. just calling next() on the cycle generator directly. zip() does the next() call for you but has a little more overhead because it creates a tuple which you unpack in the for loop.
Just to be clear the overhead is minor and I would have no issue using either of these solutions, zip() is idiomatic when trying to deal with 2 lists at the same time.
|
0

As you mention you shouldn't use a second for loop.

You can use a color_index (initial value: 0), and you increment it (modulo the number of colors) at every loop, and use it: color[color_index].

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.