Python: Iterate through listone, iterate through listtwo and apply the items from listtwo to listone

StackOverflow https://stackoverflow.com/questions/18877147

Question

I trying to APPLY colourcodes items from listtwo (actually its three lists one for each colour, r, g,b) to another list of words....The problem is there are more words than there are colours. How do I get the colour codes to restart once it comes to an end?

heres my code and attempt so far...

list of words....

listone = ["Apple","Toyota","Civic","Merc","Toshiba","Samsung","Dell","Turbo"]

lists of colours

r = [135,147,196,211]
g = [193,208,229,117]
b = [196,35,135,3] 

zippedrgb = zip(r,g,b)

for i, word in enumerate(listone):
    p=0
    y=0
    for x, colour in enumerate(zippedrgb):
        Shape.TextFrame.TextRange.Characters(res[p], charlen[y]).Font.Color = RGB(r[x],g[x],b[x])
        p+=1
        y+=1

What happens when I run this code:

from the list of words - listone - only the first four words recieve the colour, nothing happens to the remaining words.

I expected my code would to do the following....

word[1] = RGB(135,193,196)
word[2] = RGB(147,208,35)
word[3] = RGB(196,229,135)
word[4] = RGB(211,117,35)
word[5] = RGB(135,193,196)
word[6] = RGB(147,208,35)
word[7] = RGB(196,229,135)
and so on untill the words finished

As you can see, I wanted the colours to start from the begining everytime it reached the end, until the words finished...

What am I doing wrong?

Thanks...

Was it helpful?

Solution

How do I get the colour codes to restart once it comes to an end?

itertools.cycle to the rescue:

import itertools

r = [135,147,196,211]
g = [193,208,229,117]
b = [196,35,135,3] 
listone = ["Apple","Toyota","Civic","Merc","Toshiba","Samsung","Dell","Turbo"]
colours = zip(r,g,b)

colours_and_names = zip(listone,itertools.cycle(colours))
#=>  [('Apple', (135, 193, 196)), ('Toyota', (147, 208, 35)), ('Civic', (196, 229, 135)), ('Merc', (211, 117, 3)), ('Toshiba', (135, 193, 196)), ('Samsung', (147, 208, 35)), ('Dell', (196, 229, 135)), ('Turbo', (211, 117, 3))]

Now, let's fix up your code a little:

for (i, (word,colour)) in enumerate(colours_and_names):
    Shape.TextFrame.TextRange.Characters(res[i], charlen[i]).Font.Color = RGB(*colour)

You can see that with sequence assignment, you can enumerate over a zipped structure, and capture the elements into variables; and the * ("splat") operator allows you to unpack a sequence into function arguments.

Now, if you want every word in every colour, you can use product:

list(itertools.product(listone,colours))
#=> [('Apple', (135, 193, 196)), ('Apple', (147, 208, 35)), ('Apple', (196, 229, 135)), ('Apple', (211, 117, 3)), ('Toyota', (135, 193, 196)), ('Toyota', (147, 208, 35)), ('Toyota', (196, 229, 135)), ('Toyota', (211, 117, 3)), ('Civic', (135, 193, 196)), ('Civic', (147, 208, 35)), ('Civic', (196, 229, 135)), ('Civic', (211, 117, 3)), ('Merc', (135, 193, 196)), ('Merc', (147, 208, 35)), ('Merc', (196, 229, 135)), ('Merc', (211, 117, 3)), ('Toshiba', (135, 193, 196)), ('Toshiba', (147, 208, 35)), ('Toshiba', (196, 229, 135)), ('Toshiba', (211, 117, 3)), ('Samsung', (135, 193, 196)), ('Samsung', (147, 208, 35)), ('Samsung', (196, 229, 135)), ('Samsung', (211, 117, 3)), ('Dell', (135, 193, 196)), ('Dell', (147, 208, 35)), ('Dell', (196, 229, 135)), ('Dell', (211, 117, 3)), ('Turbo', (135, 193, 196)), ('Turbo', (147, 208, 35)), ('Turbo', (196, 229, 135)), ('Turbo', (211, 117, 3))]

OTHER TIPS

from itertools import cycle
list1 = ["Apple","Toyota","Civic","Merc","Toshiba","Samsung","Dell","Turbo"]
list2 = ["Blue","Red"]
print zip(list1,cycle(list2))

or slightly more old fashioned

items = []
for i in range(len(list1)):
    items.append((list1[i],list2[i%len(list2)]))
print items
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top