2013-01-14 3 views
2

Я пытаюсь повторно использовать решение в конце How to automatically generate N "distinct" colors? с использованием Python 2.7.islice на вложенных итераторах

К сожалению, код не ниже и не возвращается, так как даже если islice() запросов первые 100 итераций, то кажется, что внутренняя карта называет как

gethsvs = lambda: flatten(itertools.imap(genhsv, getfracs())) 

силы получать все итерации. Вместо того, чтобы передавать число итераций ко всем лямбда-функциям, есть ли способ сделать вызов islice() в главном коде, как показано ниже, но заставляя его получать только первые 100 итераций во всех внутренних картах?

import colorsys, itertools, numpy as np 
from fractions import Fraction 

def zenos_dichotomy(): 
    ''' 
http://en.wikipedia.org/wiki/1/2_%2B_1/4_%2B_1/8_%2B_1/16_%2B_%C2%B7_%C2%B7_%C2%B7 
    ''' 
    for k in itertools.count(): 
     yield Fraction(1, 2 ** k) 

def getfracs(): 
    ''' 
    [Fraction(0, 1), Fraction(1, 2), Fraction(1, 4), Fraction(3, 4), Fraction(1, 8), Fraction(3, 8), Fraction(5, 8), Fraction(7, 8), Fraction(1, 16), Fraction(3, 16), ...] 
    [0.0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 0.0625, 0.1875, ...] 
    ''' 
    yield 0 
    for k in zenos_dichotomy(): 
     i = k.denominator # [1,2,4,8,16,...] 
     for j in range(1, i, 2): 
      yield Fraction(j, i) 

'''Can be used for the v in hsv to map linear values 0..1 to something that looks equidistant.''' 
bias = lambda x: (np.sqrt(x/3)/Fraction(2, 3) + Fraction(1, 3))/Fraction(6, 5) 

def genhsv(h): 
    for s in [Fraction(6, 10)]: # optionally use range 
     for v in [Fraction(8, 10), Fraction(5, 10)]: # could use range too 
      yield (h, s, v) # use bias for v here if you use range 

genrgb = lambda x: colorsys.hsv_to_rgb(*x) 
flatten = itertools.chain.from_iterable 
gethsvs = lambda: flatten(itertools.imap(genhsv, getfracs())) 
getrgbs = lambda: itertools.imap(genrgb, gethsvs()) 

def genhtml(x): 
    uint8tuple = itertools.imap(lambda y: int(y * 255), x) 
    return 'rgb({},{},{})'.format(*uint8tuple) 

gethtmlcolors = lambda: map(genhtml, getrgbs()) 

if __name__ == '__main__': 
    print(list(itertools.islice(gethtmlcolors(), 100))) 
+0

совет - вы, вероятно, следует обернуть все это в класс, и использовать автономный параметров для передачи аргументов и переменных вперед и назад, так что вы можете иметь класс переменную из количество итераций, которые вы хотите использовать совместно со всеми срезами и методами, которые вы хотите. –

ответ

2

Вы используете map() вместо itertools.imap() в вашем gethtmlcolors лямбда:

gethtmlcolors = lambda: map(genhtml, getrgbs()) 

В питоне 2 map() будет пытаться обрабатывать все элементы ввода итерацию. Изменить что использовать imap() и все работает:

gethtmlcolors = lambda: itertools.imap(genhtml, getrgbs()) 
+0

Это сработало! Огромное спасибо. – Oren

Смежные вопросы